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

时间:2017-03-18 14:35:15

标签: java spring hibernate jpa spring-data-jpa

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

  

[...]嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为' messageDestinationRoomDAO'的init时出错::init方法的调用失败;嵌套异常是java.lang.IllegalArgumentException:这个类[class 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);
}

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

  

org.hibernate.AnnotationException:无法使用@Entity和@MappedSuperclass注释实体

有什么想法吗?感谢...

3 个答案:

答案 0 :(得分:0)

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

您可以将MessageDestination实体作为@MappedSuperClass进行声明,并从MessageDestination中删除@Entity。默认情况下,它的每个子类都将继承其所有字段,包括@Id字段

答案 1 :(得分:0)

等待更好的答案,因为我发现的唯一解决方案非常难看。这包括拆分主键和外键,因此存在冗余......

此:

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

答案 2 :(得分:0)

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

基本上,我正在做的错误是在抛出错误“未定义IdClass”的类中具有复合键,即,在两个成员变量上使用了一个@Id注释,由于该原因,它被认为是复合键密钥,因为在复合密钥的情况下,hibernate希望需要定义单独的密钥类,所以这种失败即将到来。