2016-07-27 25 views
23

Я настроил составной первичный ключ для моего лица Employee следующимjava.lang.IllegalArgumentException: ожидая IdClass отображение

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

Я создал фасоль SessionFactory, используя класс org.springframework.orm.hibernate5.LocalSessionFactoryBean, и сопоставил все hbm.xml как MappingLocations.

Мой код выдает следующее сообщение об ошибке:

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 

Как я могу избежать этой ошибки? Я использую spring-orm-4.3.1-RELEASE и hibernate-core-5.2.0.Final.

Update

Я создал образец проекта, и я получаю следующее сообщение об ошибке во время работы ...

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

см код: https://www.dropbox.com/s/axr8l01iqh0qr29/idclass-using-hibernate5.tar.gz?dl=0

Что я сделал не так? Просьба представить ваши входные данные здесь

+0

Что произойдет, если вы удалите @IdClass? Он должен все еще работать нормально – valepu

+0

После удаления аннотации @IdClass также я получаю ту же ошибку, что и выше. Есть ли какие-либо сопоставления, отсутствующие в создании sessionFactory? – Achaius

+0

Я пробовал с последующими 5 ansers. Но все же я получаю ту же ошибку. Я использую spring-4.3.2.RELEASE и hibernate-5.2.0.Final. – Achaius

ответ

1

Изменение к:

@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

Я попытался с этим ответом. Но наблюдая ту же ошибку, что упоминалось выше – Achaius

1

IdClass не должен быть определен как Встраиваемый -

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

А -

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

Читать ваш комментарий - Могу ли я сделать что вы сопоставляете Employee с person_id и branch_id, а не с объектами JPA и Branch? Это позволит нам проверить правильность конфигурации hbm. Id также предложить разместить свое HBM конфигурации, как я думаю, что есть информация отсутствует от этой проблемы

Так таблица будет аналогична -

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

А -

А -

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

Я попытался с вашим ответом.Но по-прежнему возникает такая же ошибка, как упоминалось выше. – Achaius

+0

Можете ли вы попробовать, чтобы сузить проблему, если ее OneToMany Mapping или IdClass, или config – farrellmr

+0

Спасибо за ваш ответ @farrellmr .. Нам нужно многоточное сопоставление в объекте person и branch, а не в поле long/integer. Просьба сообщить нам есть ли какие-либо возможности .. У меня такая же проблема с моим приложением ... – SST

3

Сочетание композитных клавиш может быть выполнено с помощью IdClass или Embeddable. Если вы хотите использовать IdClass, вы должны аннотировать свои поля в Employee с помощью @Id.

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

Если вы хотите использовать встроенный в качестве составного ключа, пожалуйста, удалить @IdClass (EmployeeId.class) аннотацию от лица. Вам также не нужно поле person и branch в вашем классе Person, потому что они определены в вашем классе Embedded.

+0

Я попробовал ваше предложение. Нашел тот же вопрос снова – Achaius

0

Упоминание @IdClass аннотация с классом, который содержит ID. Проверьте ответ на this отправлять

2

Вашей ситуация соответствует главе 2.4.1 Первичных ключей, соответствующие произведенные идентичности из JPA 2.1 Specification.

Личность Employee получена из тождеств Person и Branch. Вы не указали код ни одного из них, поэтому я предполагаю, что у них простые первичные ключи. В этом отношении Person и Branch являются «родительскими объектами», а Employee является «зависимым» объектом.

Идентификатор Employee может быть сопоставлен либо с IdClass, либо с EmbeddedId, но не одновременно.

См. Главу 2.4.1.1 Спецификация производных тождеств.

Если вы хотите использовать IdClass, то:

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.

Так что ваши классы будут выглядеть следующим образом (геттеры, сеттеры, лишние аннотации и т.д.) опущенных

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

Если вы используете EmbeddedId, затем:

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.

И код будет выглядеть так:

@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

Спасибо @Adam Michalik попробовал ваш ответ, но все равно получаю ту же ошибку. Любые другие предложения – Achaius

0

Эта ссылка может помочь вам JPA - EmbeddedId with @ManytoOne

отображения Отношения, определенные в внедренного идентификатор класса не supported.Then вам нужно изменить класс embeddedId как этот

@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 Основной ключ

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.

Ответ здесь. прочитайте описание для вас. enter link description here

(образец кода)

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