当前位置: 首页 > 知识库问答 >
问题:

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

卢聪
2023-03-14

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

[...]嵌套异常是org.springframework.beans.factory.BeanCreationException:错误创建bean与名称的消息目的地RoomDAO:调用init方法失败;嵌套异常是java.lang.IllegalArgumentException:这个类[类com.chat.message.entity.MessageDestinationRoom]没有定义一个IdClass

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

    @OneToOne(targetEntity = MessageDestination.class,
              cascade=CascadeType.ALL, mappedBy="msg")
    @NotNull
    private MessageDestination dest;

    //...
}

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class MessageDestination implements Serializable {      
    @Id @OneToOne(cascade=CascadeType.ALL)
    private Message msg;
}

@Entity
public class MessageDestinationRoom extends MessageDestination {        
    @OneToOne @NotNull
    private Room destRoom;

    //...
}

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

为了解决这个问题,我看到我可以将MessageDestation注释为@MapedSuperclass,但这不起作用,因为它需要是@Entity才能存储在Message中。可悲的是,这是不可能的:

org.hibernate.注释异常:实体不能同时使用@Entity和@MapedSuperclass进行注释

有什么想法吗?谢谢


共有3个答案

侯博易
2023-03-14

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

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

步博艺
2023-03-14

等待更好的答案,因为我发现的唯一解决方案相当丑陋。这包括拆分主键和外键,所以有冗余...

这个:

@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);
}
燕靖
2023-03-14

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

您可以将MessageDestination实体注释为@MappedSuperClass,并从MessageDestination中删除@Entity。默认情况下,其每个子类将继承其所有字段,包括@Id字段

 类似资料:
  • “我想从Hello类获取用户Id的值,但无法从Hello world的goldUser获取。获取@Idclass”未为实体指定标识符:“错误。” 我做错了什么,或者应该用什么方法从Hello表中获取用户id的值。

  • “我想从Hello类获取Hello world的goldUser的用户Id值,但无法获取该值。正在获取@IDClass”未为实体指定标识符:“错误”。“ 我做错了什么,或者应该用什么方法从Hello表中获取用户id的值。

  • 对不起,我的英语不是我的母语,而且已经两点钟了,所以现在不能思考了。现在,在将hibernate与Java和PostgreSQL一起使用时,我遇到了下一个问题:我有如下实体Human和User(带有注释映射): 和数据库结构如下: 当我尝试运行我的项目(简单单元测试)时,我得到下一个错误: (我剪掉了日志的尾部,而它在JUnit方法中响应invokin)。 生成的查询(失败): 可以看到,它试图在

  • 面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。 大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。 ES6 引入了 class

  • 本文向大家介绍JavaScript中的继承之类继承,包括了JavaScript中的继承之类继承的使用技巧和注意事项,需要的朋友参考一下 继承简介       在JS中继承是一个非常复杂的话题,比其他任何面向对象语言中的继承都复杂得多。在大多数其他面向对象语言中,继承一个类只需使用一个关键字即可。在JS中想要达到继承公用成员的目的,需要采取一系列措施。JS属于原型式继承,得益于这种灵活性,我们既可以

  • 本文向大家介绍ABAP 继承-定义,包括了ABAP 继承-定义的使用技巧和注意事项,需要的朋友参考一下 示例 信息 继承使您可以从现有类派生新类。您可以使用的INHERITING FROM加法 从超类继承的CLASS子类DEFINITION 继承 。 声明。新的类子类继承了现有类超类的所有组件。新类称为派生类的子类。原始类称为新类的超类。一个类可以有多个直接子类,但可能只有一个直接超类。 类的实现