Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.lang.IllegalArgumentException:应为IdClass映射_Java_Spring 4_Sessionfactory_Hibernate 5.x_Spring Orm - Fatal编程技术网

java.lang.IllegalArgumentException:应为IdClass映射

java.lang.IllegalArgumentException:应为IdClass映射,java,spring-4,sessionfactory,hibernate-5.x,spring-orm,Java,Spring 4,Sessionfactory,Hibernate 5.x,Spring Orm,我已经为我的实体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 emp

我已经为我的实体
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;
    }
}
我使用class
org.springframework.orm.hibernate5.LocalSessionFactoryBean
创建了一个
SessionFactory
bean,并将所有
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
请参阅代码:

我做错了什么?请在此处提供您的输入更改为:

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

}

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;
    }
}
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;
    }
}
阅读您的评论-我可以建议您将员工映射到person_id和branch_id,而不是JPA对象person和branch吗?这将让我们测试您的hbm配置是否正确。我还建议发布你的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 Person person;
    private Branch branch;

    public EmployeeId() {}

    public EmployeeId(Person argPerson, Branch argbranch) {
        this.person = argPerson;
        this.branch = argbranch;
    }
}
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;
    }
}
及-

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

复合密钥映射可以使用IdClass或可嵌入密钥来完成。如果要使用IdClass,必须在Employee中的字段上添加@Id注释

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

如果您想使用嵌入式作为复合键,请从Person中删除@IdClass(EmployeeId.class)注释。您也不需要person类中的person和branch字段,因为它们是在嵌入式类中定义的。

使用包含
ID
的类提及
@IdClass
注释。
检查post上的答案

您的情况与第2.4.1章主键对应,主键对应于源代码的派生标识

员工
的身份来源于
人员
分支机构
的身份。您没有显示其中任何一个的代码,因此我假设它们有简单的主键。在这种关系中,
个人
分支机构
是“父实体”
员工
是“从属”实体

Employee
的ID可以使用
IdClass
EmbeddedId
进行映射,而不是同时使用两者

参见第2.4.1.1章衍生身份的规范

如果要使用
IdClass
,则:

id类的属性名称和从属实体类的id属性名称必须如下所示:

  • 实体类中的
    Id
    属性和Id类中的相应属性必须具有相同的名称

  • 如果实体中的
    Id
    属性与父实体是多对一或一对一关系,则Id类中的相应属性必须是父实体的
    Id
    属性的类型(…)
所以您的类看起来是这样的(省略了getter、setter、多余的注释等)

如果使用
EmbeddedId
,则:

如果依赖实体使用嵌入id表示其主键,则与关系属性对应的嵌入id中的属性必须与父实体的主键类型相同,并且必须由应用于关系属性的
MapsId
注释指定。必须使用
MapsId
注释的
value
元素指定关系属性所对应的嵌入id中的属性名称

代码如下所示:

@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
}
这个链接可以帮助你

不支持在嵌入式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;
    }
}

JPA复合主键

指定映射到实体的多个字段或属性的复合主键类

主键类和 实体的主键字段或属性必须对应且 它们的类型必须相同

答案就在这里。为您阅读描述

(示例代码)


如果删除@IdClass会发生什么?在删除@IdClass注释后,它仍然可以正常工作,而且我得到了与上面相同的错误。SessionFactorybean创建中是否缺少任何映射?我尝试了以下5种方法。但我还是犯了同样的错误。我使用的是spring-4.3.2.RELEASE和hibernate-5.2.0.Final。@Achaius-在测试中,您试图让员工没有公司或团队。但团队和公司是员工的ID-它们不能为空。除了公司和团队之外,您的员工还有一个
id
字段-您希望将哪个字段用作id-company+团队还是
id
字段?您需要更多地介绍您的设计/需求,然后我们可能会提供帮助。目前这种模式在很多地方都是错误的。不过,我还是设法克服了你提到的错误。我试着回答了你的问题。但是仍然会出现与上面提到的相同的错误。如果是OneToMany映射或IdClass,或者Config,您可以尝试上面的方法缩小问题的范围吗谢谢您的回复@farrellmr。。我们需要在person和branch对象中使用多通映射,而不是长/整数字段。。请告诉我们是否有任何可能性。。我的应用程序也有同样的问题…老实说,Id切换到EmbeddedId-原始类的问题是它混合了IdClass和EmbeddedId,这造成了问题。根据我的经验,EmbeddedId更容易使用我尝试过这个答案。但是,鉴于上述同样的错误,我尝试了你的建议。再次发现同样的问题Hank you@Adam Michalik尝试了你的答案,但仍然得到同样的错误。还有其他建议吗