I have some problems with inheritance mapping. Here my database structure:
And associated entities:
@MappedSuperclass
public abstract class AbstractEntity<ID extends Serializable> implements Serializable {
@Id @GeneratedValue(strategy = IDENTITY)
@Column(unique = true, updatable = false, nullable = false)
private ID id;
public ID getId() {
return id;
}
@SuppressWarnings("unused")
public void setId(ID id) {
this.id = id;
}
@Entity @Table(name = "user_activity")
@Inheritance(strategy = JOINED)
@AttributeOverride(name = "id", column = @Column(name = "ua_id"))
public abstract class UserActivity extends AbstractEntity<Long> {
@ManyToOne(cascade = { MERGE, PERSIST }, fetch = LAZY)
@JoinColumn(name = "ua_user_id")
private User user;
...
}
@Entity @Table(name = "comment")
@PrimaryKeyJoinColumn(name = "cm_id")
public class Comment extends UserActivity {
@ManyToOne(cascade = { MERGE, PERSIST }, fetch = LAZY)
@JoinColumn(name = "cm_question_id")
private Question question;
...
}
@Entity @Table(name = "question")
@PrimaryKeyJoinColumn(name = "qs_id")
public class Question extends UserActivity {
...
@OneToMany(fetch = LAZY, cascade = ALL, mappedBy = "question")
private List<Answer> answers = new ArrayList<>();
@OneToMany(fetch = LAZY, cascade = ALL, mappedBy = "question")
private List<Comment> comments = new ArrayList<>();
...
}
@Entity @Table(name = "answer")
@PrimaryKeyJoinColumn(name = "asw_id")
public class Answer extends UserActivity {
@ManyToOne(cascade = { MERGE, PERSIST }, fetch = LAZY)
@JoinColumn(name = "asw_question_id")
private Question question;
...
}
@Entity @Table(name = "user")
@AttributeOverride(name = "id", column = @Column(name = "user_id"))
public class User extends AbstractEntity<Long> {
...
@OneToMany(cascade = REMOVE)
private List<Question> questions = new ArrayList<>();
@OneToMany(cascade = REMOVE)
private List<Answer> answers = new ArrayList<>();
@OneToMany(cascade = REMOVE)
private List<Comment> comments = new ArrayList<>();
...
}
When I try to save or delete a User
I get an exceptions:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [insert into user_question (user_user_id, questions_qs_id) values (?, ?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
and:
org.hibernate.engine.jdbc.spi.SqlExceptionHelper : 147 = user lacks privilege or object not found: USER_ANSWER
Hibernate is trying to create a table: user_question
and user_answer
which me do not need.
What I should doing for fixes ?
I don't think you can achieve this by mapping the ManyToOne
association to User
generically in the UserActivity
entity. That's probably too confusing for the JPA provider (Hibernate).
Instead, I think you need to map the association to User
in each of the Question
, Answer
and Comment
entities. Yes, I know that would be duplicated code, but it looks like the only way you will then be able to qualify the OneToMany
mappings in User
using the mappedBy
reference.
For instance, your Question
entity would have an association defined as:
@ManyToOne(cascade = { MERGE, PERSIST }, fetch = LAZY)
@JoinColumn(name = "ua_user_id")
private User questionUser;
Depending on how clever (or not) Hibernate is about the above association, you may need to specify the table="USER_ACTIVITY"
in the JoinColumn
annotation.
Then the User
would have the OneToMany as:
@OneToMany(mappedBy="questionUser", cascade = REMOVE)
private List<Question> questions = new ArrayList<>();
Similarly for each of Answer
and Comment
.
Of course, I haven't tried this, so I could be wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With