web-dev-qa-db-ja.com

java.lang.IllegalArgumentException:IdClassマッピングが必要です

エンティティEmployeeの複合プライマリキーを次のように構成しました

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を使用してSessionFactory Beanを作成し、すべてのhbm.xmlMappingLocationsとしてマップしました。

私のコードは次のエラーをスローします:

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-RELEASEhibernate-core-5.2.0.Finalを使用しています。

更新

サンプルプロジェクトを作成しましたが、実行中に次のエラーが表示されます...

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=

私が間違ったことは何ですか?ここに入力してください

23
Achaius

複合キーマッピングは、IdClassまたはEmbeddableで実行できます。 IdClassを使用する場合は、@ Idを使用してEmployeeのフィールドに注釈を付ける必要があります。

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

Embeddedを複合キーとして使用する場合は、Personから@IdClass(EmployeeId.class)注釈を削除してください。また、Personクラスのpersonおよびbranchフィールドは、Embeddedクラスで定義されているため必要ありません。

3
Mr.Stef

あなたの状況は JPA 2.1仕様 の章2.4.1派生IDに対応する主キーに対応しています。

EmployeeのIDは、PersonおよびBranchのIDから派生します。どちらのコードも表示されていないため、単純な主キーがあると仮定します。その関係では、PersonBranchは「親エンティティ」であり、Employeeは「依存」エンティティです。

EmployeeのIDは、IdClassまたはEmbeddedIdのいずれかを使用してマップできますが、両方を同時に使用することはできません。

2.4.1.1派生IDの仕様の章を参照してください。

IdClassを使用する場合:

Idクラスの属性の名前と依存エンティティクラスのId属性は、次のように対応する必要があります。

  • エンティティークラスのId属性とidクラスの対応する属性は同じ名前でなければなりません。

...

  • エンティティのId属性が親エンティティとの多対1または1対1の関係である場合、idクラスの対応する属性は(...)親のId属性の型である必要がありますエンティティ。

したがって、クラスは次のようになります(ゲッター、セッター、余分な注釈などは省略されます)

@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を使用する場合:

依存エンティティが埋め込みIDを使用してそのプライマリキーを表す場合、リレーションシップ属性に対応する埋め込みIDの属性は、親エンティティのプライマリキーと同じタイプである必要があり、適用されるMapsIdアノテーションで指定する必要があります関係属性。リレーションシップ属性が対応する埋め込みID内の属性の名前を指定するには、valueアノテーションのMapsId要素を使用する必要があります。

そして、コードは次のようになります。

@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

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

コメントを読む-JPAオブジェクトのPersonとBranchではなく、person_idとbranch_idにEmployeeをマップすることを提案できますか?これにより、hbm設定が正しいかどうかをテストできます。また、この問題から情報が欠落していると思うので、hbm configを投稿することをお勧めします

そのため、テーブルは次のようになります-

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

への変更:

@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

このリンクはあなたを助けることができます JPA-@ManytoOneのEmbeddedId

埋め込みIDクラス内で定義されたリレーションシップマッピングはサポートされていません。次に、このように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
SEY_91

IDを保持するクラスに@IdClass注釈を付けます。 this postで答えを確認してください

0
Akash Mishra

JPAコンポジット主キー

エンティティの複数のフィールドまたはプロパティにマップされる複合主キークラスを指定します。

主キークラスのフィールドまたはプロパティの名前と、エンティティの主キーフィールドまたはプロパティは対応している必要があり、それらのタイプは同じである必要があります。

答えはここにあります。説明を読んでください。 ここにリンクの説明を入力してください

(サンプルコード)

@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