Reputation: 73
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
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