2016-07-27 2 views
23

j'ai configuré clé primaire composite pour mon entité Employee comme suitjava.lang.IllegalArgumentException: la cartographie d'attendre

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 en utilisant la classe org.springframework.orm.hibernate5.LocalSessionFactoryBean et mappé tous hbm.xml comme MappingLocations.

Mon code jette 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.

Mise à jour

J'ai créé un exemple de projet et j'obtiens l'erreur suivante lors de l'exécution ...

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

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

Ce que je fait de mal? Veuillez fournir vos entrées ici

+0

Qu'advient-il si vous supprimez @IdClass? Il devrait encore fonctionner correctement – valepu

+0

Après avoir supprimé l'annotation @IdClass, j'obtiens la même erreur que ci-dessus. Des mappages sont-ils manquants dans la création du bean sessionFactory? – Achaius

+0

J'ai essayé avec 5 ansers suivants. Mais encore je reçois la même erreur. J'utilise spring-4.3.2.RELEASE et hibernate-5.2.0.Final. – Achaius

Répondre

1

Change to:

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

} 
+0

J'ai essayé avec cette réponse. Mais en observant la même erreur que mentionné ci-dessus – Achaius

1

Le IdClass ne devrait pas être défini 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 faire une suggestion que vous mappez Employee à person_id et branch_id, et pas les objets JPA Person and Branch? Cela nous permettra de tester si votre configuration hbm est correcte. Id suggèrent également afficher votre config hbm que je pense qu'il manque des informations de ce problème

Ainsi, la table sera similaire à -

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

j'ai essayé avec votre réponse.Mais toujours obtenir la même erreur que mentionné ci-dessus. – Achaius

+0

Pouvez-vous essayer ci-dessus pour affiner le problème si c'est le OneToMany Mapping ou IdClass, ou config – farrellmr

+0

Merci pour votre réponse @farrellmr .. Nous avons besoin de cartographie ManyToOne dans un objet personne et branche pas un champ long/entier .. Veuillez nous le faire savoir Y at-il des possibilités .. J'ai le même problème avec mon application ... – SST

3

Un mappage de touches composites peut être effectué avec une IdClass ou un Embedded. Si vous voulez utiliser une 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 un Embarqués comme une clé composite s'il vous plaît raye la mention @IdClass (EmployeeId.class) de personne. Vous n'avez également pas besoin du champ de personne et de branche dans votre classe Personne, car ceux-ci sont définis dans votre classe Embedded.

+0

J'ai essayé votre suggestion. Nous avons encore trouvé le même problème – Achaius

0

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

2

Votre situation correspond au chapitre 2.4.1 clés primaires correspondant à Identités dérivées du JPA 2.1 Specification. L'identité de Employee est dérivée des identités de Person et de Branch. Vous n'avez pas montré le code de l'un d'entre eux, donc je suppose qu'ils ont des clés primaires simples. Dans cette relation, Person et Branch sont des «entités parentes» et Employee est une entité «dépendante».

L'ID de Employee peut être mis en correspondance utilisant IdClass ou EmbeddedId, pas les deux en même temps.

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

Si vous souhaitez utiliser IdClass, puis:

The names of the attributes of the id class and the Id attributes of the dependent entity class must correspond as follows:

  • The Id attribute in the entity class and the corresponding attribute in the id class must have the same name.

...

  • If an Id attribute in the entity is a many-to-one or one-to-one relationship to a parent entity, the corresponding attribute in the id class must be of (...) the type of the Id attribute of the parent entity.

donc vos classes ressemblerait à 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, puis:

If the dependent entity uses an embedded id to represent its primary key, the attribute in the embedded id corresponding to the relationship attribute must be of the same type as the primary key of the parent entity and must be designated by the MapsId annotation applied to the relationship attribute. The value element of the MapsId annotation must be used to specify the name of the attribute within the embedded id to which the relationship attribute corresponds.

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 
} 
+0

Merci @Adam Michalik a essayé votre réponse, mais toujours la même erreur. D'autres suggestions – Achaius

0

Ce lien pourrait vous aider JPA - EmbeddedId with @ManytoOne

applications de relations définies dans une classe id intégré ne sont pas supported.Then vous devez changer la classe EmbeddedId comme celui-ci

@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

JPA Composite Clé primaire

Specifies a composite primary key class that is mapped to multiple fields or properties of the entity.

The names of the fields or properties in the primary key class and the primary key fields or properties of the entity must correspond and their types must be the same.

La réponse est ici. lisez la description pour vous. enter link description here

(code échantillon)

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