#java #hibernate
#java #спящий режим
Вопрос:
Я пытался следовать этой статье, потому что при пакетных обновлениях я получаю ненужные выборки с помощью слияния:
for(int i = 0; i< elements.size(); i ){
Query q = em.createQuery("select p from Parent p join fetch p.child c where p.id=:id", Parent.class);
//parameter of :id from elements
Parent p = q.getSingleResult();
p.setName("aname"); //for simplicity just the name member
myList.add(p);
}
utx = com.arjuna.ats.jta.UserTransaction.userTransaction();
utx.begin();
em.joinTransaction();
for(int i = 0; i< myList.size(); i ){
if (i > 0 amp;amp; i % Common.BATCH_SIZE == 0) { //BATCH_SIZE=50
em.flush();
em.clear();
}
Parent myObject = myList.get(i);
em.merge(myObject);
}
utx.commit();
Это мое определение сущности:
@Entity
@Table(name = "myparenttable", schema = "myschema", catalog = "mydb")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Parent implements Serializable {
private Integer id_parent;
private String name;
@JsonManagedReference
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private List<Child> children;
//getters and setters
@JsonInclude(JsonInclude.Include.NON_NULL)
@OneToMany(mappedBy = "parent", targetEntity = Child.class, fetch = FetchType.LAZY,cascade = {CascadeType.PERSIST, CascadeType.MERGE})
public Set<Child> getChildren() {
return this.children;
}
public void setChildren(Set<Child> children) {
this.children = children;
}
}
@Entity
@Table(name = "mychildtable", schema = "myschema", catalog = "mydb")
public class Child implements Serializable {
private Integer id_child;
private String description;
@JsonBackReference
private Parent parent;
//getters and setters
}
Следуя упомянутой статье, я изменил свой код следующим образом:
utx = com.arjuna.ats.jta.UserTransaction.userTransaction();
utx.begin();
em.joinTransaction();
Session session = em.unwrap( Session.class );
for(int i = 0; i< myList.size(); i ){
if (i > 0 amp;amp; i % Common.BATCH_SIZE == 0) { //BATCH_SIZE=50
em.flush();
em.clear();
}
Parent myObject = elements.get(i);
session.update(myObject);
}
utx.commit();
Однако, когда список меньше BATCH_SIZE (<50), изменения сделаны правильно, тогда необходимы инструкции flush и clear, я получаю эту ошибку:
detached entity passed to persist: Child
Я также пробовал:
session.flush();
session.clear();
С точно такой же ошибкой. Я чего-то не хватает?
Ответ №1:
Вы проверили, содержит ли список повторяющиеся объекты? Если один пакет попытается обновить объект с одним и тем же идентификатором дважды, вы можете столкнуться с этой проблемой.