2016-07-27 47 views
23

mam skonfigurowane kompozytowy klucz podstawowy dla mojej jednostki Employee następującojava.lang.IllegalArgumentException: oczekiwano IdClass mapowanie

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

Stworzyłem fasolę SessionFactory przy użyciu klasy org.springframework.orm.hibernate5.LocalSessionFactoryBean i zmapowałem wszystkie hbm.xml jako.

Mój kod wyrzuca następujący błąd:

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 

Jak mogę uniknąć tego błędu? Używam spring-orm-4.3.1-RELEASE i hibernate-core-5.2.0.Final.

Aktualizacja

ja stworzyliśmy przykładowy projekt i otrzymuję następujący błąd podczas uruchamiania ...

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

Patrz kod: https://www.dropbox.com/s/axr8l01iqh0qr29/idclass-using-hibernate5.tar.gz?dl=0

co zrobiłem źle? Proszeni są twoi wejść tutaj

+0

Co się dzieje, jeśli usunąć @IdClass? To powinno nadal działać dobrze – valepu

+0

Po usunięciu adnotacji @IdClass również otrzymuję taki sam błąd jak powyżej. Czy w tworzeniu komponentu bean sesji nie ma żadnych mapowań? – Achaius

+0

Próbowałem z 5 obserwacjami. Ale wciąż dostaję ten sam błąd. Używam spring-4.3.2.RELEASE i hibernate-5.2.0.Final. – Achaius

Odpowiedz

1

zmienić na:

@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

Próbowałem z tą odpowiedzią. Ale obserwując ten sam błąd, o którym wspomniano powyżej – Achaius

1

IdClass nie powinno być zdefiniowane jako niezabudowany -

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

oraz -

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

Przeczytaj komentarz - Mogę zrobić sugestię, aby odwzorować pracownika na id_osobisty i numer_rozdziału, a nie na osoby i jednostki WZP? To pozwoli nam przetestować, czy twoja konfiguracja hbm jest poprawna. Id sugerują również opublikowania swojej HBM config, jak myślę, nie ma informacji brakuje tego problemu

więc tabela będzie podobna do -

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

oraz -

oraz -

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

Próbowałem z twoją odpowiedzią.Ale wciąż pojawia się ten sam błąd, o którym wspomniano powyżej. – Achaius

+0

Czy możesz spróbować powyżej, aby zawęzić problem, jeśli jest to OneToMany Mapping lub IdClass, lub konfiguracja – farrellmr

+0

Dzięki za odpowiedź @farrellmr .. Potrzebujemy mapowania ManyToOne w obiekcie osoby i gałęzi, a nie pola long/integer .. Uprzejmie informujemy nas czy są jakieś możliwości ... Mam taki sam problem z moją aplikacją ... – SST

3

Mapowanie złożonego klucza można wykonać za pomocą IdClass lub Embeddable. Jeśli chcesz użyć IdClass, musisz zanotować pola w Employee przy pomocy @Id.

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

Jeśli chcesz użyć wbudowanego w kluczu złożonym usuń @IdClass (EmployeeId.class) adnotację od osoby. Nie potrzebujesz również pola person i branch w klasie Person, ponieważ są one zdefiniowane w klasie Embedded.

+0

Próbowałem twojej sugestii. Znów znalazłem ten sam problem – Achaius

0

Wspomnieć o adnotacji z klasą, która posiada ID. Sprawdź odpowiedzi na this zakładać

2

Twoja sytuacja odpowiada rozdziale 2.4.1 Podstawowe przyciski odpowiadające Derived Tożsamości z JPA 2.1 Specification.

Tożsamość Employee pochodzi od tożsamości Person i Branch. Nie pokazałeś kodu żadnego z nich, więc zakładam, że mają proste klucze podstawowe. W tym związku Person i Branch są "elementami nadrzędnymi", a Employee jest jednostką "zależną".

Identyfikator Employee może być odwzorowany przy użyciu IdClass lub EmbeddedId, a nie obu jednocześnie.

Zobacz rozdział 2.4.1.1 Specyfikacja pochodnych tożsamości.

Jeśli chcesz użyć IdClass, a następnie:

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.

więc zajęcia będzie wyglądać następująco (pobierające, ustawiaczy, zbędnych opisów itp pominięte)

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

Jeśli używasz EmbeddedId, następnie:

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.

Kod powinien wyglądać tak:

@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

Dziękuję @Adam Michalik próbował twojej odpowiedzi, ale wciąż otrzymywał ten sam błąd. Jakieś inne sugestie – Achaius

0

Ten link może pomóc JPA - EmbeddedId with @ManytoOne

mapowania Powiązania zdefiniowanych w osadzonym Identyfikator klasy nie są supported.Then trzeba zmienić klasę embeddedId jak ten

@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

WZP Composite Klucz podstawowy

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.

Odpowiedź jest tutaj. przeczytaj opis dla ciebie. enter link description here

(Przykładowy kod)

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