tutorial mediante libro framework español ejemplo desarrollo aplicaciones java hibernate jpa java-ee

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.



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