Note that there are some explanatory texts on larger screens.

plurals
  1. POJPA with Hibernate - merge performance issues
    text
    copied!<p>I stumbled on a problem with <code>merge</code> method of <code>EntityManager</code>.</p> <p>I have this class</p> <pre><code>@Entity public class QuestionList { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; @ManyToOne private UserEntity user; @OneToMany(cascade = CascadeType.ALL) private List&lt;QuestionUnit&gt; units = new ArrayList&lt;QuestionUnit&gt;(); public List&lt;QuestionUnit&gt; getUnits() { return units; } public void setUnits(List&lt;QuestionUnit&gt; units) { this.units = units; } public Long getId() { return id; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void addQuestionUnit(QuestionUnit QuestionUnit) { this.units.add(QuestionUnit); } public void setUser(UserEntity user) { this.user = user; } public UserEntity getUser() { return this.user; } } </code></pre> <p>now, if I just modify one of the objects in <code>units</code> the merge is fine, but if I delete or add new object to the collection, the way that merge happens is that I am getting <code>delete from QuestionList_QuestionUnit where QuestionList_id=?</code> and then every row is added one by one <code>insert into QuestionList_QuestionUnit (QuestionList_id, units_id) values (?, ?)</code></p> <p>I am wondering, is it possible to tell JPA/Hibernate to just add/delete the row associated with the object added/deleted? Or is it the way that merge just works with collections and in my case I need to write my own query for updating the database.</p> <p>I am asking because this collection can be potentially pretty huge, and just deleting all rows and inserting almost all of them again doesn't seems like a good way to update the table.</p> <p>EDIT: as requested:</p> <pre><code>@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class QuestionUnit { @Id @GeneratedValue(strategy = GenerationType.TABLE) private long id; @OneToOne(cascade = CascadeType.ALL) private AnswerUnit correctAnswer; public QuestionUnit(AnswerUnit correctAnswer) { this.correctAnswer = correctAnswer; } public void setCorrectAnswer(AnswerUnit correctAnswer) { this.correctAnswer = correctAnswer; } public AnswerUnit getCorrectAnswer() { return this.correctAnswer; } public long getId() { return id; } public void setId(long id){ this.id=id; } public abstract Object getQuestionContent(); public abstract String getTitle(); } </code></pre> <p>there are 3 concrete classes in this hierarchy, for example</p> <pre><code>@Question("openQuestion") @Entity public class OpenQuestion extends QuestionUnit { public void setQuestionContent(String questionContent) { this.questionContent = questionContent; } private String questionContent; public OpenQuestion() { this(null, new OpenQuestionAnswer()); } public OpenQuestion(String questionContent, AnswerUnit correctAnswer) { super(correctAnswer); this.questionContent = questionContent; } public String getQuestionContent() { return this.questionContent; } public String getTitle() { return questionContent; } } @Transactional(propagation = Propagation.REQUIRED) public void update(QuestionList questionList) { entityManager.merge(questionList); } </code></pre> <p>this method is used for all updates, because the list is in the detached state.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload