java - mediante - spring framework pdf español
JPA Múltiples campos integrados (4)
Al usar Eclipse Link, una alternativa al uso de AttributeOverrides es usar un SessionCustomizer. Esto resuelve el problema para todas las entidades de una sola vez:
public class EmbeddedFieldNamesSessionCustomizer implements SessionCustomizer {
@SuppressWarnings("rawtypes")
@Override
public void customize(Session session) throws Exception {
Map<Class, ClassDescriptor> descriptors = session.getDescriptors();
for (ClassDescriptor classDescriptor : descriptors.values()) {
for (DatabaseMapping databaseMapping : classDescriptor.getMappings()) {
if (databaseMapping.isAggregateObjectMapping()) {
AggregateObjectMapping m = (AggregateObjectMapping) databaseMapping;
Map<String, DatabaseField> mapping = m.getAggregateToSourceFields();
ClassDescriptor refDesc = descriptors.get(m.getReferenceClass());
for (DatabaseMapping refMapping : refDesc.getMappings()) {
if (refMapping.isDirectToFieldMapping()) {
DirectToFieldMapping refDirectMapping = (DirectToFieldMapping) refMapping;
String refFieldName = refDirectMapping.getField().getName();
if (!mapping.containsKey(refFieldName)) {
DatabaseField mappedField = refDirectMapping.getField().clone();
mappedField.setName(m.getAttributeName() + "_" + mappedField.getName());
mapping.put(refFieldName, mappedField);
}
}
}
}
}
}
}
}
¿Es posible que una clase de entidad JPA contenga dos campos incrustados ( @Embedded
)? Un ejemplo sería:
@Entity
public class Person {
@Embedded
public Address home;
@Embedded
public Address work;
}
public class Address {
public String street;
...
}
En este caso, una Person
puede contener dos instancias de Address
: casa y trabajo. Estoy usando JPA con la implementación de Hibernate. Cuando genero el esquema usando Hibernate Tools, solo incrusta una Address
. Lo que me gustaría es dos instancias de Address
incrustadas, cada una con sus nombres de columna distinguidos o pre-añadidos con algún prefijo (como el hogar y el trabajo). Sé de @AttributeOverrides
, pero esto requiere que cada atributo se @AttributeOverrides
forma individual. Esto puede volverse engorroso si el objeto incrustado ( Address
) se agranda, ya que cada columna debe sobrescribirse individualmente.
En caso de que esté utilizando Hibernate, también puede usar un esquema de nombres diferente que agrega prefijos únicos a las columnas para campos incrustados idénticos. Consulte Agregar un prefijo automáticamente a los nombres de columna para las clases @Embeddable
La forma genérica de JPA para hacerlo es con @AttributeOverride. Esto debería funcionar tanto en EclipseLink como en Hibernate.
@Entity
public class Person {
@AttributeOverrides({
@AttributeOverride(name="street",column=@Column(name="homeStreet")),
...
})
@Embedded public Address home;
@AttributeOverrides({
@AttributeOverride(name="street",column=@Column(name="workStreet")),
...
})
@Embedded public Address work;
}
@Embeddable public class Address {
@Basic public String street;
...
}
}
Si desea tener el mismo tipo de objeto incrustable dos veces en la misma entidad, el valor predeterminado del nombre de la columna no funcionará: al menos una de las columnas tendrá que ser explícita. Hibernate va más allá de la especificación EJB3 y le permite mejorar el mecanismo predeterminado a través de NamingStrategy. DefaultComponentSafeNamingStrategy es una pequeña mejora sobre la EJB3NamingStrategy predeterminada que permite que los objetos incrustados sean predeterminados incluso si se usan dos veces en la misma entidad.
De Hibernate Annotations Doc: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e714