Java ~";“未定义IdClass”;在JpaRepository中,对于继承的@OneToOne@Id

Java ~";“未定义IdClass”;在JpaRepository中,对于继承的@OneToOne@Id,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,我试图创建一个jpa存储库,但外键主键有问题。尽管它是在抽象基类(MessageDestination)中指定的,但它似乎在专门的MessageDestination类的存储库中是不可见的(例如MessageDestinationRoom) […]嵌套异常为org.springframework.beans.factory.BeanCreationException:创建名为“messageDestinationRoomDAO”的bean时出错:调用init方法失败;嵌套的异常是java.lan

我试图创建一个jpa存储库,但外键主键有问题。尽管它是在抽象基类(
MessageDestination
)中指定的,但它似乎在专门的
MessageDestination
类的存储库中是不可见的(例如
MessageDestinationRoom

[…]嵌套异常为org.springframework.beans.factory.BeanCreationException:创建名为“messageDestinationRoomDAO”的bean时出错:调用init方法失败;嵌套的异常是java.lang.IllegalArgumentException:此类[class com.chat.message.entity.MessageDestinationRoom]未定义IdClass

@Entity@heritance(策略=heritancetype.TABLE\u PER\u类)
公共抽象类消息实现可序列化{
@Id@GeneratedValue(策略=GenerationType.TABLE)
私人长id;
@OneToOne(targetEntity=MessageDestination.class,
cascade=CascadeType.ALL,mappedBy=“msg”)
@NotNull
私有消息目的地;
//...
}
@实体@inheritation(策略=InheritanceType.TABLE每类)
公共抽象类MessageDestination实现可序列化{
@OneToOne的Id(级联=级联类型.ALL)
私人消息消息消息;
}
@实体
公共类MessageDestinationRoom扩展MessageDestination{
@OneToOne@NotNull
私人房间休息室;
//...
}
公共接口MessageDestinationRoomDAO
扩展JPA假设{
公共集findMessageDestinationRoomByDestRoom
(目的地房间);
}
为了解决这个问题,我看到我可以将
MessageDestination
注释为
@MappedSuperclass
,但这不起作用,因为它需要是
@实体才能存储在
Message
中。遗憾的是,这是不可能的:

org.hibernate.AnnotationException:不能同时使用@entity和@MappedSuperclass对实体进行注释


有什么想法吗?谢谢…

因为您使用的是逐类表继承策略,并且没有任何映射的超类(因此每个实体都必须有自己的id)


您可以将MessageDestination实体注释为@MappedSuperClass,并从MessageDestination中删除@Entity。默认情况下,它的每个子类都会继承它的所有字段,包括@Id字段,以获得更好的答案,因为我发现的唯一解决方案非常难看。这包括拆分主键和外键,因此存在冗余

这:

@Entity@heritance(策略=heritancetype.TABLE\u PER\u类)
公共抽象类MessageDestination实现可序列化{
@OneToOne的Id(级联=级联类型.ALL)
私人消息消息消息;
}
公共接口MessageDestinationRoomDAO
扩展JPA假设{
公共集findMessageDestinationRoomByDestRoom
(目的地房间);
}
变成这样:

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class MessageDestination implements Serializable {      
    @Id @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;

    @OneToOne(cascade=CascadeType.ALL)
    private Message msg;
}

interface MessageDestinationRoomDAO
extends JpaRepository<MessageDestinationRoom, Long> {
    public Set<MessageDestinationRoom> findMessageDestinationRoomByDestRoom
        (Room dest);
}
@Entity@heritance(策略=heritancetype.TABLE\u PER\u类)
抽象类MessageDestination实现可序列化{
@Id@GeneratedValue(策略=GenerationType.TABLE)
私人长id;
@OneToOne(级联=级联类型.ALL)
私人消息消息消息;
}
接口消息DestinationRoomDAO
扩展JPA假设{
公共集findMessageDestinationRoomByDestRoom
(目的地房间);
}

当我使用基于@oneToMany和@ManyToOne注释的映射时,我也遇到了同样的问题


基本上,我犯的错误是在抛出错误的类中“没有定义IdClass”具有复合键,即在两个成员变量上使用了多个@Id注释,因此它被视为复合键,并且由于hibernate希望在复合键的情况下需要定义一个单独的键类,因此出现了此故障

已经试过了。实际上,我对每个类使用
TABLE\u,而不是
SINGLE\u TABLE
策略。您的建议触发以下异常:org.hibernate.AnnotationException:Unknown mappedBy in:com.test.Message.dest,引用属性Unknown:com.test.MessageDestination.msg。谢谢你抽出时间。:)
@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class MessageDestination implements Serializable {      
    @Id @OneToOne(cascade=CascadeType.ALL)
    private Message msg;
}

public interface MessageDestinationRoomDAO
extends JpaRepository<MessageDestinationRoom, Message> {
    public Set<MessageDestinationRoom> findMessageDestinationRoomByDestRoom
        (Room dest);
}
@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
abstract class MessageDestination implements Serializable {      
    @Id @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;

    @OneToOne(cascade=CascadeType.ALL)
    private Message msg;
}

interface MessageDestinationRoomDAO
extends JpaRepository<MessageDestinationRoom, Long> {
    public Set<MessageDestinationRoom> findMessageDestinationRoomByDestRoom
        (Room dest);
}