Skip to content
Advertisement

JPA and Hibernate, OneToMany relationship with a composite key using UUID

I’m using SpringBoot with JPA and Hibernate.

I have two entities: Book and Author. A Book can have multiple Authors. So I need a OneToMany relationship.

Into the Author table, my idea is to use a composite key (the book_id and one internal field for example field_a)

I implemented these classes:

@Entity
@Table(name = "book")
public class Book extends MyBaseEntity {

    @Id
    @Column(name = "id")
    @Type(type = "uuid-char")
    private UUID uuid = UUID.randomUUID();

    @Column(name = "name", nullable = false)
    private String name;

    @OneToMany(mappedBy = "book")
    private List<Author> authors = new ArrayList<>();

}

@Entity
@Table(name = "author")
public class Author extends MyBaseEntity {

    @EmbeddedId
    private CustomID id;

    @ManyToOne()
    @MapsId("bookId")
    @JoinColumn(name = "book_id")
    private Book book;

    @Column(name = "field_a", nullable = false)
    @MapsId("fieldA")
    @Type(type = "uuid-char")
    private UUID fieldA;

}


@Embeddable
public class CustomID implements Serializable {

    @Column(name = "book_id")
    private UUID bookId;

    @Column(name = "field_a")
    private UUID fieldA;

    public CustomID() { }

    public CustomID(UUID bookId, UUID fieldA) {
        this.bookId = bookId;
        this.fieldA = fieldA;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass())
            return false;

        ShareID that = (CustomID) o;
        return Objects.equals(bookId, that.bookId) &&
                Objects.equals(fieldA, that.fieldA);
    }

    @Override
    public int hashCode() {
        return Objects.hash(bookId, fieldA);
    }
}

When I try to execute my project (I’m using the property spring.jpa.hibernate.ddl-auto=create to generate the DB) I’m obtaining this error:

ERROR SpringApplication-reportFailure():837 - [ Application run failed ]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unknown entity name: java.util.UUID 

Any suggestion?

If I try to remove the use of composite-key works fine so, probably the problem it’s related to the implementation or use of the composite key.

Advertisement

Answer

Use either an ID class with Author as:

@Entity
@Table(name = "author")
@IdClass(CustomID.class)
public class Author extends MyBaseEntity {

    @Id
    @ManyToOne()
    @JoinColumn(name = "book_id")
    private Book book;

    @ID
    @Column(name = "field_a", nullable = false)
    @Type(type = "uuid-char")
    private UUID fieldA;

}

public class CustomID implements Serializable {
    //these match the names of the property marked with @Id in Author
    private UUID book;
    private UUID fieldA;
}

Or an embeddable that defines the basic fields for your entity as you have already done:

@Entity
@Table(name = "author")
public class Author extends MyBaseEntity {

    @EmbeddedId
    private CustomID id;

    @ManyToOne()
    @MapsId("bookId")
    @JoinColumn(name = "book_id")
    private Book book;
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement