Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA mapping @ManyToOne between Embeddable and EmbeddedId

I have the following setup in my Spring Boot JPA application:

Embeddable

@Embeddable
public class LogSearchHistoryAttrPK {
    @Column(name = "SEARCH_HISTORY_ID")
    private Integer searchHistoryId;

    @Column(name = "ATTR", length = 50)
    private String attr;

    @ManyToOne
    @JoinColumn(name = "ID")
    private LogSearchHistory logSearchHistory;
    ...
}

EmbeddedId

@Repository
@Transactional
@Entity
@Table(name = "LOG_SEARCH_HISTORY_ATTR")
public class LogSearchHistoryAttr implements Serializable {
    @EmbeddedId
    private LogSearchHistoryAttrPK primaryKey;

    @Column(name = "VALUE", length = 100)
    private String value;
    ...
}

OneToMany

@Repository
@Transactional
@Entity
@Table(name = "LOG_SEARCH_HISTORY")
public class LogSearchHistory implements Serializable {
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    private Integer id;

    @OneToMany(mappedBy = "logSearchHistory", fetch = FetchType.EAGER)
    private List<LogSearchHistoryAttr> logSearchHistoryAttrs;
    ...
}

Database DDLs

CREATE TABLE log_search_history (
    id serial NOT NULL,
    ...
    CONSTRAINT log_search_history_pk PRIMARY KEY (id)
 );

CREATE TABLE log_search_history_attr (
    search_history_id INTEGER NOT NULL,
    attr CHARACTER VARYING(50) NOT NULL,
    value CHARACTER VARYING(100),
    CONSTRAINT log_search_history_attr_pk PRIMARY KEY (search_history_id, attr),
    CONSTRAINT log_search_history_attr_fk1 FOREIGN KEY (search_history_id) REFERENCES
        log_search_history (id)
);

When I go to start the application, I get the following error:

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.foobar.entity.LogSearchHistoryAttr.logSearchHistory in com.foobar.entity.LogSearchHistory.logSearchHistoryAttrs

I am not sure why I am getting this error - the mapping looks correct (to me). What is wrong with this mapping that I have? Thanks!

like image 977
Ascalonian Avatar asked Mar 18 '16 12:03

Ascalonian


People also ask

Can embeddable class be used as primary key?

Introduction to Composite Primary Keys and Primary Key Classes. The EJB 3.0 specification allows you to define a primary key class as a @Embeddable and use it as the primary key of your Entity bean. One or more properties can be used as members of the primary key for that particular table.

What is @EmbeddedId in JPA?

Annotation Type EmbeddedIdApplied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable .

What is the use of @EmbeddedId?

@EmbeddedId is used for composite primary key. i.e. more than one column behaves jointly as primary key. We need to create an entity as Embeddable and the Embeddable entity can be embedded in other entity to achieve composite primary key.

Which of the following is the correct use case for @EmbeddedId annotation?

The use of @Id with a class marked as @Embeddable is the most natural approach. The @Embeddable tag can be used for non-primary key embeddable values anyway. It allows you to treat the compound primary key as a single property, and it permits the reuse of the @Embeddable class in other tables.


2 Answers

You moved the mappedBy attribute into an embeddable primary key, so the field is no longer named logSearchHistory but rather primaryKey.logSearchHistory. Change your mapped by entry:

@OneToMany(mappedBy = "primaryKey.logSearchHistory", fetch = FetchType.EAGER)
private List<LogSearchHistoryAttr> logSearchHistoryAttrs;

Reference: JPA / Hibernate OneToMany Mapping, using a composite PrimaryKey.

You also need to make the primary key class LogSearchHistoryAttrPK serializable.

like image 74
K.Nicholas Avatar answered Oct 04 '22 21:10

K.Nicholas


At OneToMany part:

@OneToMany(mappedBy = "primaryKey.logSearchHistory", fetch = FetchType.EAGER)
private List<LogSearchHistoryAttr> logSearchHistoryAttrs;
like image 21
lukaszwrzaszcz Avatar answered Oct 04 '22 23:10

lukaszwrzaszcz