简体   繁体   中英

~“IdClass not defined” in JpaRepository, for an inherited @OneToOne @Id

I'm trying to create a jpa repository but there is a problem with a foreign-key primary-key. Although it is specified in the abstract base class ( MessageDestination ), it seems to be invisible from the repository of specialized MessageDestination class (eg MessageDestinationRoom ).

[...] nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageDestinationRoomDAO': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: This class [class com.chat.message.entity.MessageDestinationRoom] does not define an 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);
}

To solve the issue I saw that I can annotate MessageDestination as a @MappedSuperclass , but this can't work because it needs to be an @Entity to be stored in Message . Sadly, it's not possible:

org.hibernate.AnnotationException: An entity cannot be annotated with both @Entity and @MappedSuperclass

Any ideas? Thanks...

Since you are using table per class inheritance strategy and you dont have any mapped superclass (so each entity must have its own id).

You can annonate your MessageDestination Entity as @MappedSuperClass and remove the @Entity from MessageDestination. As by default its each subclass will inherited all its field including the @Id field

Pending for a better answer because the only solution I found is quite ugly. That consists of splitting the primary and the foreign key, so there is redundancy...

This:

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

becomes this:

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

I was also getting same issue when I was using @oneToMany And @ManyToOne Annotation based Mapping.

Basically what I was doing mistake was in the class that was throwing the error "does not define an IdClass" was having composite Keys ie More that one @Id annotation used over two member variables due to which it was getting considered as Composite Key and since hibernate expects a seperate Key class needs to be defined in case of composite key this failure was coming.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM