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 deId
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 devalue
de la anotaciónMapsId
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;
...
}