web-dev-qa-db-fra.com

java.lang.IllegalArgumentException: mappage IdClass en attente

J'ai configuré la clé primaire composite pour mon entité Employee comme suit

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;
    }
}

J'ai créé un bean SessionFactory à l'aide de la classe org.springframework.orm.hibernate5.LocalSessionFactoryBean et mappé tout hbm.xml en tant que MappingLocations.

Mon code génère l'erreur suivante:

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

Comment puis-je éviter cette erreur? J'utilise spring-orm-4.3.1-RELEASE et hibernate-core-5.2.0.Final.

Mettre à jour

J'ai créé un exemple de projet et l'erreur suivante s'affiche pendant l'exécution ...

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

Reportez-vous au code: https://www.dropbox.com/s/axr8l01iqh0qr29/idclass-using-hibernate5.tar.gz?dl=0

Qu'est-ce que j'ai mal fait? Veuillez fournir vos informations ici

23
Achaius

Un mappage de clé composite peut être effectué avec un IdClass ou un Embeddable. Si vous souhaitez utiliser une classe IdClass, vous devez annoter vos champs dans Employee avec @Id. 

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

Si vous souhaitez utiliser une clé incorporée en tant que clé composite, supprimez l'annotation @IdClass (EmployeeId.class) de Person. De plus, vous n'avez pas besoin des champs personne et branche de votre classe Person car ceux-ci sont définis dans votre classe Embedded.

3
Mr.Stef

Votre situation correspond au chapitre 2.4.1 Clés principales correspondant aux identités dérivées de Spécification JPA 2.1 .

L'identité de Employee est dérivée des identités de Person et Branch. Vous n'avez montré le code d'aucun d'eux, alors je suppose qu'ils ont des clés primaires simples. Dans cette relation, Person et Branch sont des "entités mères" et Employee est une entité "dépendante".

L'ID de Employee peut être mappé à l'aide de IdClass ou EmbeddedId, et non des deux en même temps.

Voir le chapitre 2.4.1.1 Spécification des identités dérivées.

Si vous voulez utiliser IdClass, alors:

Les noms des attributs de la classe id et les attributs id de la classe d'entité dépendante doivent correspondre comme suit:

  • L'attribut Id dans la classe d'entité et l'attribut correspondant dans la classe id doivent avoir le même nom.

...

  • Si un attribut Id dans l'entité est une relation plusieurs-à-un ou un-à-un avec une entité parent, l'attribut correspondant dans la classe id doit être du type (...) du type de l'attribut Id du parent entité.

Ainsi, vos classes ressembleraient à ceci (getters, setters, annotations superflues, etc. omis)

@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 vous utilisez EmbeddedId, alors:

Si l'entité dépendante utilise un identifiant incorporé pour représenter sa clé primaire, l'attribut dans l'identifiant incorporé correspondant à l'attribut de relation doit être du même type que la clé primaire de l'entité mère et doit être désigné par l'annotation MapsId appliquée à l'élément. attribut de relation. L'élément value de l'annotation MapsId doit être utilisé pour spécifier le nom de l'attribut dans l'ID incorporé auquel l'attribut de relation correspond. 

Et le code ressemblerait à ceci:

@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
}
2
Adam Michalik

La classe IdClass ne devrait pas être définie comme intégrable -

@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() { }
   //....
}

Et - 

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;
    }
}

Lisez votre commentaire. Puis-je suggérer de mapper Employee à person_id et branch_id, et non aux objets JPA Personne et Branch? Cela nous permettra de tester si votre configuration hbm est correcte. Id suggère également de publier votre configuration hbm car je pense qu’il manque des informations à ce problème.

Donc, la table sera semblable à -

@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() { }
   //....
}

Et - 

Et - 

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;
    }
}
1
farrellmr

Changer en:

@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;
}

}
1
Sirsendu

Ce lien pourrait vous aider JPA - EmbeddedId with @ManytoOne

Les mappages de relations définis dans une classe id intégrée ne sont pas pris en charge. Ensuite, vous devez modifier la classe embeddedId de la manière suivante

@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;
    }
}
0
SEY_91

Mentionnez l'annotation @IdClass avec la classe qui contient la ID. Vérifiez la réponse à this post 

0
Akash Mishra

Clé primaire composite JPA

Spécifie une classe de clé primaire composite mappée sur plusieurs champs ou propriétés de l'entité.

Les noms des champs ou des propriétés dans la classe de clé primaire et le les champs de clé primaire ou les propriétés de l'entité doivent correspondre et leurs types doivent être les mêmes.

La réponse est ici. lire la description pour vous. entrez la description du lien ici

(Exemple de code) 

@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;
  ...
}
0
Byeon0gam