example java spring-4 sessionfactory hibernate-5.x spring-orm

example - java.lang.IllegalArgumentException: espera la asignación de IdClass



spring boot hibernate 5 mysql example (7)

Cambiar a:

@Entity @Table(name = "employee") @Proxy(lazy = false) @IdClass(EmployeeId.class) public class Employee implements Serializable { private static final long serialVersionUID = 1L; private EmployeeId id; private Person person; private Branch branch; private boolean isActive; public Employee() { } @EmbeddedId @AttributeOverrides({@AttributeOverride(name = "person", column = @Column(name = "person_id") ), @AttributeOverride(name = "branch", column = @Column(name = "branch_id") )}) public EmployeeId getId() { return id; } public void setId(EmployeeId id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "person_id") public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "branch_id") public Branch getBranch() { return branch; } public void setBranch(Branch branch) { this.branch = branch; } @Column(name = "is_active") public boolean getIsActive() { return isActive; } public void setIsActive(boolean isActive) { this.isActive = isActive; } }

He configurado la clave primaria compuesta para mi Employee entidad de la siguiente manera

Employee.java:

@Entity @Table(name="employee") @Proxy(lazy=false) @IdClass(EmployeeId.class) public class Employee implements Serializable { private static final long serialVersionUID = 1L; private EmployeeId employeeId; private Person person; private Branch branch; private boolean isActive; public Employee() { } @EmbeddedId @AttributeOverrides({ @AttributeOverride(name="person", column = @Column(name="person_id")), @AttributeOverride(name="branch", column = @Column(name="branch_id"))}) public EmployeeId getEmployeeId() { return employeeId; } public void setEmployeeId(EmployeeId employeeId) { this.employeeId = employeeId; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="person_id") public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="branch_id") public Branch getBranch() { return branch; } public void setBranch(Branch branch) { this.branch = branch; } @Column(name="is_active") public boolean getIsActive() { return isActive; } public void setIsActive(boolean isActive) { this.isActive = isActive; } }

EmployeeId.java:

@Embeddable public class EmployeeId implements Serializable { private static final long serialVersionUID = 1L; private Person person; private Branch branch; public EmployeeId() { } public EmployeeId(Person argPerson, Branch argbranch) { this.person = argPerson; this.branch = argbranch; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="person_id", insertable=false, updatable=false) public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="branch_id", insertable=false, updatable=false) public Branch getBranch() { return branch; } public void setBranch(Branch branch) { this.branch = branch; } }

org.springframework.orm.hibernate5.LocalSessionFactoryBean un bean SessionFactory utilizando la clase org.springframework.orm.hibernate5.LocalSessionFactoryBean y hbm.xml todos los hbm.xml como MappingLocations .

Mi código arroja el siguiente error:

Caused by: java.lang.IllegalArgumentException: expecting IdClass mapping at org.hibernate.metamodel.internal.AttributeFactory$3.resolveMember(AttributeFactory.java:971) at org.hibernate.metamodel.internal.AttributeFactory$5.resolveMember(AttributeFactory.java:1029) at org.hibernate.metamodel.internal.AttributeFactory.determineAttributeMetadata(AttributeFactory.java:451) at org.hibernate.metamodel.internal.AttributeFactory.buildIdAttribute(AttributeFactory.java:128) at org.hibernate.metamodel.internal.MetadataContext.buildIdClassAttributes(MetadataContext.java:337) at org.hibernate.metamodel.internal.MetadataContext.applyIdMetadata(MetadataContext.java:269) at org.hibernate.metamodel.internal.MetadataContext.wrapUp(MetadataContext.java:190) at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:219) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:296) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:476) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:707) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:723) at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:504) at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:488) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFac

¿Cómo puedo evitar este error? Estoy usando spring-orm-4.3.1-RELEASE y hibernate-core-5.2.0.Final .

Actualizar

He creado un proyecto de ejemplo y recibo el siguiente error mientras ejecuto ...

Caused by: org.hibernate.AnnotationException: Property of @IdClass not found in entity sample.domain.Employee: employee

Consulte el código: https://www.dropbox.com/s/axr8l01iqh0qr29/idclass-using-hibernate5.tar.gz?dl=0

¿Que hice mal? Por favor proporcione sus entradas aquí


El IdClass no debería ser definido como Embebible -

@Entity @Table(name="employee") @IdClass(EmployeeId.class) public class Employee implements Serializable { private static final long serialVersionUID = 1L; @Id @ManyToOne private Person person; @Id @ManyToOne private Branch branch; private boolean isActive; public Employee() { } //.... }

Y -

public class EmployeeId implements Serializable { private static final long serialVersionUID = 1L; private Person person; private Branch branch; public EmployeeId() {} public EmployeeId(Person argPerson, Branch argbranch) { this.person = argPerson; this.branch = argbranch; } }

Lea su comentario: ¿Puedo hacer una sugerencia de que asigne Employee a person_id y branch_id, y no a los objetos JPA Person y Branch? Esto nos permitirá probar si su configuración de hbm es correcta. También sugiero publicar su configuración hbm ya que creo que falta información sobre este problema

Así que la tabla será similar a

@Entity @Table(name="employee") @IdClass(EmployeeId.class) public class Employee implements Serializable { private static final long serialVersionUID = 1L; @Id private Long personId; @Id private Long branchId; private boolean isActive; public Employee() { } //.... }

Y -

Y -

public class EmployeeId implements Serializable { private static final long serialVersionUID = 1L; private Long personId; private Long branchId; public EmployeeId() {} public EmployeeId(Person argPerson, Branch argbranch) { this.person = argPerson; this.branch = argbranch; } }


Este enlace puede ayudarle a JPA - EmbeddedId con @ManytoOne

Las asignaciones de relaciones definidas dentro de una clase de identificación incorporada no son compatibles. Entonces, necesita cambiar la clase embeddedId de esta manera

@Embeddable public class EmployeeId implements Serializable { private static final long serialVersionUID = 1L; private Long personId; private Long branchId; public EmployeeId() { } public EmployeeId(Long argPerson, Long argbranch) { this.personId = argPerson; this.branchId = argbranch; } @Column(name = "person_id") public Long getPersonId() { return personId; } public void setPersonId(Long personId) { this.personId = personId; } @Column(name = "branch_id") public Long getBranchId() { return branchId; } public void setBranchId(Long branchId) { this.branchId = branchId; } }


Mencione la anotación de @IdClass con la clase que contiene el ID . Comprueba la respuesta en this post.


Su situación corresponde al capítulo 2.4.1 Claves primarias correspondientes a las identidades derivadas de la especificación JPA 2.1 .

La identidad del Employee se deriva de las identidades de Person y Branch . No has mostrado el código de ninguno de ellos, así que asumiré que tienen claves primarias simples. En esa relación, Person y Branch son "entidades principales" y el Employee es una entidad "dependiente".

El ID de Employee se puede asignar utilizando IdClass o EmbeddedId , no ambos al mismo tiempo.

Ver capítulo 2.4.1.1 Especificación de Identidades Derivadas .

Si quieres usar IdClass , entonces:

Los nombres de los atributos de la clase de identificación y los atributos de identificación de la clase de entidad dependiente deben corresponder de la siguiente manera:

  • El atributo Id en la clase de entidad y el atributo correspondiente en la clase id deben tener el mismo nombre.

...

  • Si un atributo de Id en la entidad es una relación de muchos a uno o uno a uno con una entidad de padres, el atributo correspondiente en la clase de ID debe ser de (...) el tipo del atributo de Id del padre entidad.

Por lo que sus clases se verían así (omitidos, definidores, anotaciones superfluas, etc.)

@Entity @IdClass(EmployeeId.class) public class Employee { @Id @ManyToOne private Person person; @Id @ManyToOne private Branch branch; } public class EmployeeId { private Long person; // Corresponds to the type of Person ID, name matches the name of Employee.person private Long branch; // Corresponds to the type of Branch ID, name matches the name of Employee.branch }

Si usa EmbeddedId , entonces:

Si la entidad dependiente utiliza una identificación incorporada para representar su clave primaria, el atributo en la identificación incorporada correspondiente al atributo de relación debe ser del mismo tipo que la clave primaria de la entidad principal y debe ser designado por la anotación MapsId aplicada a la atributo de relación. El elemento de value de la anotación MapsId debe usar para especificar el nombre del atributo dentro de la identificación incrustada a la que corresponde el atributo de relación.

Y el código se vería así:

@Entity public class Employee { @EmbeddedId private EmployeeId id; @ManyToOne @MapsId("personId") // Corresponds to the name of EmployeeId.personId private Person person; @ManyToOne @MapsId("branchId") // Corresponds to the name of EmployeeId.branchId private Branch branch; } @Embeddable public class EmployeeId { private Long personId; // Corresponds to the type of Person ID private Long branchId; // Corresponds to the type of Branch ID }


Una asignación de clave compuesta se puede realizar con una IdClass o con Embeddable. Si desea utilizar un IdClass, debe anotar sus campos en Empleado con @Id.

@IdClass(EmployeeId.class) class Person{ @Id private Person person; @Id private Branch branch; }

Si desea utilizar una incrustación como clave compuesta, elimine la anotación @IdClass (EmployeeId.class) de la persona. Tampoco necesita el campo persona y rama en su clase Persona porque están definidos en su clase Incrustada.


Clave primaria compuesta JPA

Especifica una clase de clave primaria compuesta que se asigna a múltiples campos o propiedades de la entidad.

Los nombres de los campos o propiedades en la clase de clave primaria y los campos de clave primaria o propiedades de la entidad deben corresponder y sus tipos deben ser los mismos.

La respuesta está aquí. Lee la descripción para ti. ingrese la descripción del enlace aquí

(Código de muestra)

@Entity @Table(name = "EMP_PROJECT") @IdClass(ProjectAssignmentId.class) public class ProjectAssignment { @Id @Column(name = "EMP_ID", insertable = false, updatable = false) private int empId; @Id @Column(name = "PROJECT_ID", insertable = false, updatable = false) private int projectId; @ManyToOne @JoinColumn(name = "EMP_ID") Professor employee; @ManyToOne @JoinColumn(name = "PROJECT_ID") Project project; .... } public class ProjectAssignmentId implements Serializable { private int empId; private int projectId; ... }