type fecha false example column anotaciones java hibernate jpa annotations

fecha - jpa java



CombinaciĆ³n de varias columnas en Hibernate/JPA (3)

Esto funcionó para mí. En mi caso, las dos tablas foo y boo se deben unir en base a 3 columnas diferentes. Tenga en cuenta que en mi caso, las 3 columnas comunes no son clave principal

es decir, mapeo uno a uno basado en 3 columnas diferentes

@Entity @Table(name = "foo") public class foo implements Serializable { @Column(name="foocol1") private String foocol1; //add getter setter @Column(name="foocol2") private String foocol2; //add getter setter @Column(name="foocol3") private String foocol3; //add getter setter private Boo boo; private int id; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "brsitem_id", updatable = false) public int getId() { return this.id; } public void setId(int id) { this.id = id; } @OneToOne @JoinColumns( { @JoinColumn(updatable=false,insertable=false, name="foocol1", referencedColumnName="boocol1"), @JoinColumn(updatable=false,insertable=false, name="foocol2", referencedColumnName="boocol2"), @JoinColumn(updatable=false,insertable=false, name="foocol3", referencedColumnName="boocol3") } ) public Boo getBoo() { return boo; } public void setBoo(Boo boo) { this.boo = boo; } } @Entity @Table(name = "boo") public class Boo implements Serializable { private int id; @Column(name="boocol1") private String boocol1; //add getter setter @Column(name="boocol2") private String boocol2; //add getter setter @Column(name="boocol3") private String boocol3; //add getter setter @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "item_id", updatable = false) public int getId() { return id; } public void setId(int id) { this.id = id; } }

Tengo dos entidades a las que me gustaría unir a través de varias columnas. Estas columnas son compartidas por un objeto @Embeddable que es compartido por ambas entidades. En el siguiente ejemplo, Foo solo puede tener una Bar pero Bar puede tener varias Foo s (donde AnEmbeddableObject es una clave exclusiva para Bar ). Aquí hay un ejemplo:

@Entity @Table(name = "foo") public class Foo { @Id @Column(name = "id") @GeneratedValue(generator = "seqGen") @SequenceGenerator(name = "seqGen", sequenceName = "FOO_ID_SEQ", allocationSize = 1) private Long id; @Embedded private AnEmbeddableObject anEmbeddableObject; @ManyToOne(targetEntity = Bar.class, fetch = FetchType.LAZY) @JoinColumns( { @JoinColumn(name = "column_1", referencedColumnName = "column_1"), @JoinColumn(name = "column_2", referencedColumnName = "column_2"), @JoinColumn(name = "column_3", referencedColumnName = "column_3"), @JoinColumn(name = "column_4", referencedColumnName = "column_4") }) private Bar bar; // ... rest of class }

Y la clase de Bar:

@Entity @Table(name = "bar") public class Bar { @Id @Column(name = "id") @GeneratedValue(generator = "seqGen") @SequenceGenerator(name = "seqGen", sequenceName = "BAR_ID_SEQ", allocationSize = 1) private Long id; @Embedded private AnEmbeddableObject anEmbeddableObject; // ... rest of class }

Finalmente la clase AnEmbeddedObject :

@Embeddable public class AnEmbeddedObject { @Column(name = "column_1") private Long column1; @Column(name = "column_2") private Long column2; @Column(name = "column_3") private Long column3; @Column(name = "column_4") private Long column4; // ... rest of class }

Obviamente, el esquema está pobremente normalizado, es una restricción para que los campos de AnEmbeddedObject se repitan en cada tabla.

El problema que tengo es que recibo este error cuando intento iniciar Hibernate:

org.hibernate.AnnotationException: referencedColumnNames(column_1, column_2, column_3, column_4) of Foo.bar referencing Bar not mapped to a single property

He intentado marcar las JoinColumns no se pueden insertar ni actualizar, pero sin suerte. ¿Hay alguna manera de expresar esto con las anotaciones Hibernate / JPA?


Hibernate no le va a hacer más fácil hacer lo que está tratando de hacer. De la documentación de Hibernate :

Tenga en cuenta que cuando se utiliza referencedColumnName en una columna de clave no primaria, la clase asociada debe ser serializable. También tenga en cuenta que el referencedColumnName a una columna de clave no primaria debe asignarse a una propiedad que tenga una sola columna (es posible que otros casos no funcionen). (énfasis añadido)

Por lo tanto, si no está dispuesto a hacer de AnEmbeddableObject el identificador de la barra, Hibernate no irá perezosamente, recupere la barra automáticamente. Por supuesto, puede seguir utilizando HQL para escribir consultas que se unan en AnEmbeddableObject , pero pierde la búsqueda automática y el mantenimiento del ciclo de vida si insiste en usar una clave no primaria de columnas múltiples para la barra.


Si esto no funciona me quedo sin ideas. De esta manera, obtiene las 4 columnas en ambas tablas (ya que Bar posee y Foo usa para hacer referencia a la Bar ) y los ID generados en ambas entidades. El conjunto de 4 columnas debe ser único en la Bar para que la relación de muchos a uno no se convierta en muchos a muchos.

@Embeddable public class AnEmbeddedObject { @Column(name = "column_1") private Long column1; @Column(name = "column_2") private Long column2; @Column(name = "column_3") private Long column3; @Column(name = "column_4") private Long column4; } @Entity public class Foo { @Id @Column(name = "id") @GeneratedValue(generator = "seqGen") @SequenceGenerator(name = "seqGen", sequenceName = "FOO_ID_SEQ", allocationSize = 1) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumns({ @JoinColumn(name = "column_1", referencedColumnName = "column_1"), @JoinColumn(name = "column_2", referencedColumnName = "column_2"), @JoinColumn(name = "column_3", referencedColumnName = "column_3"), @JoinColumn(name = "column_4", referencedColumnName = "column_4") }) private Bar bar; } @Entity @Table(uniqueConstraints = @UniqueConstraint(columnNames = { "column_1", "column_2", "column_3", "column_4" })) public class Bar { @Id @Column(name = "id") @GeneratedValue(generator = "seqGen") @SequenceGenerator(name = "seqGen", sequenceName = "BAR_ID_SEQ", allocationSize = 1) private Long id; @Embedded private AnEmbeddedObject anEmbeddedObject; }