Java 将@manytone休眠为具有@IdClass的实体之一

Java 将@manytone休眠为具有@IdClass的实体之一,java,spring-boot,hibernate,jpa,spring-data-jpa,Java,Spring Boot,Hibernate,Jpa,Spring Data Jpa,我刚刚在我的项目中添加了一个新实体,但现在它没有启动。 我认为这与@ManyToOne作为复合键的一部分有关,但我不确定。 我将问题归结为以下实体: A.课程: @Tablename=A @实体 @IdClassKeyA.class 公共A类{ @身份证 私人援助; @身份证 @许多酮 私人B,; 公共字符串getaId{ 返回援助; } 公共无效设置辅助字符串辅助{ 这个。援助=援助; } 公共广播{ 返回b; } 公共图书馆{ 这个.b=b; } } B.等级: @Tablename=B @

我刚刚在我的项目中添加了一个新实体,但现在它没有启动。 我认为这与@ManyToOne作为复合键的一部分有关,但我不确定。 我将问题归结为以下实体:

A.课程:

@Tablename=A @实体 @IdClassKeyA.class 公共A类{ @身份证 私人援助; @身份证 @许多酮 私人B,; 公共字符串getaId{ 返回援助; } 公共无效设置辅助字符串辅助{ 这个。援助=援助; } 公共广播{ 返回b; } 公共图书馆{ 这个.b=b; } } B.等级:

@Tablename=B @实体 @IdClassKeyB.class 公共B级{ @身份证 串标; @身份证 字符串bId2; 公共字符串getbId{ 退还投标书; } 公开招标{ this.bId=投标; } 公共字符串getbId2{ 返回标书2; } 公共无效setbId2String bId2{ this.bId2=bId2; } } KeyA.class:

公共类KeyA实现了可序列化{ 私人援助; 私有字符串b; } 钥匙类

公共类KeyB实现了可序列化{ 公开招标; 公共字符串2; } 引发异常:

        Error creating bean with name 'entityManagerFactory' defined in class path resource
        [...]
        Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer]
    [...]
    Caused by: java.lang.reflect.InvocationTargetException: null
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_201]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_201]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_201]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_201]
        at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:104) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        ... 43 common frames omitted
    Caused by: org.hibernate.PropertyNotFoundException: Could not locate field name [bId] on class [java.lang.String]
        at org.hibernate.internal.util.ReflectHelper.findField(ReflectHelper.java:371) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.property.access.internal.PropertyAccessFieldImpl.<init>(PropertyAccessFieldImpl.java:34) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.property.access.internal.PropertyAccessStrategyFieldImpl.buildPropertyAccess(PropertyAccessStrategyFieldImpl.java:26) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.mapping.Property.getGetter(Property.java:311) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.tuple.component.PojoComponentTuplizer.buildGetter(PojoComponentTuplizer.java:141) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
我尝试了一切,包括导入最新的javassist。 我正在运行Java1.8上的SpringBoot2.2.5.RELEASE,它也发生在

它的结构就像B只有一个字符串ID,这里称为B,而实际上它本身有一个复合键

public class KeyB implements Serializable{

    public String bId;
    public String bId2;
}
因此,您必须更改KeyA以正确表示该关系:

public class KeyA implements Serializable {

    private String aId;
    private KeyB keyB;
}
您的

它的结构就像B只有一个字符串ID,这里称为B,而实际上它本身有一个复合键

public class KeyB implements Serializable{

    public String bId;
    public String bId2;
}
因此,您必须更改KeyA以正确表示该关系:

public class KeyA implements Serializable {

    private String aId;
    private KeyB keyB;
}
您应该在KeyA中使用与所属实体中标记为@Id的字段名称/类型完全相同的字段名称/类型

因此,您应该按照以下方式更正KeyA:

公共类KeyA实现了可序列化{ 私人援助; 私人B,; } 请参阅。

中的进一步解释和示例。您应该在您的KeyA中使用与自有实体中标记为@Id的字段名称/类型完全相同的名称/类型

因此,您应该按照以下方式更正KeyA:

公共类KeyA实现了可序列化{ 私人援助; 私人B,; }
请参阅中的进一步解释和示例。

我认为您的答案是正确的,但密钥B应该是B实体本身。不,只有当您的实体没有复合PKI时,这才有效。您的实体刚刚对其进行了双向测试,并且它只与私有B一起工作;有趣的是,我很确定几年前我也这么做了,它只适用于PK级别上的IdClass引用我只找到了,但它们使用的是EmbeddedId。我认为你的答案是正确的,但是键B应该是B实体本身。不,只有当您的实体没有复合PKI时才有效,因为它只是通过两种方式对其进行测试,并且它只与私有B一起工作;有趣的是,我很确定几年前我也这么做了,它只适用于PK级别上的IdClass引用我只找到了,但他们在那里使用EmbeddedId,我看到了,表示您需要的复合键的复合键。谢谢大家!@CarlosLópezMaríI我已经更新了答案,看起来Smutje的答案可以更正为可行。这很奇怪,我会重新检查它,它可能是一个休眠错误。你是否通过键B中的两列加入B?事实上,第二种方法效果更好,因为它修复了第一次检索实体eith childs时出现的错误:我明白了,要指示复合键的复合键,您需要它。谢谢大家!@CarlosLópezMaríI我已经更新了答案,看起来Smutje的答案可以更正为可行。奇怪的是,我会重新检查它,它可能是一个休眠错误。你是否通过键B中的两列加入B?事实上,第二种方法效果更好,因为它修复了第一次检索实体eith childs时出现的错误: