Cuneyt
Cuneyt

Reputation: 73

JPA/Hibernate SingleTable Inheritance - Sub class can not persist relations defined in the super class

I have a single table inheritance hierarchy in jpa as shown below:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(catalog = "onedb", name = "content")
@DiscriminatorColumn(name = "oid_content_type", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Content implements Serializable {
   ...
   @OneToMany(cascade = CascadeType.PERSIST)
   @JoinColumn(name = "oid_content", referencedColumnName = "oid_content")
   private List<ContentKeyword> keywords;
   ...

@Entity
public abstract class RichMedia extends Content {
  ... 
    @OneToMany(mappedBy="richMedia", cascade =CascadeType.PERSIST)
    private Set<RichMediaFile> richMediaFiles;
 ...

 }

 @Entity
 @DiscriminatorValue("1")
 public class RichMediaImage extends RichMedia {}

As can be seen Content is the top most base class, RichMedia is the base class for RichMediaImage and Content has a list of ContentKeyword as defined as below:

 @Entity
 @Table(catalog = "onedb", name="content_keyword")
 public class ContentKeyword implements Serializable {
    ...
     @ManyToOne
     @JoinColumn(name = "oid_content")
     private Content content;
 }

I construct a RichMediaImage and set the list of ContentKeyword on it and try to persist the whole object. The single table, content is inserted with a new row and a new id is generated but when it comes to insert into the content_keyword table this new id is not provided in the sql jpa generates:

 insert into onedb.content_keyword (oid_content, keyword) values (NULL, 'test') 

throwing

MySQLIntegrityConstraintViolationException: Column 'oid_content' cannot be null

I'd greatly appreciate any pointers.

Upvotes: 0

Views: 1311

Answers (1)

JB Nizet
JB Nizet

Reputation: 691865

Your mapping is incorrect. In a bidirectional OneToMany association, the one side must be the inverse side of the many side:

@OneToMany(mappedBy = "content", cascade = CascadeType.PERSIST)
private List<ContentKeyword> keywords;

And JPA only considers the owner side when it comes to the assicoation. So adding a keyword to a content is not sufficient. You must also set the content in the keyword:

content.getKeywords().add(keyword);
keyword.setContent(content);

Upvotes: 1

Related Questions