EntityManager.merge (obj) удаляет вместо обновления или выдает нулевую ошибку

#java #hibernate #jpa #entitymanager

#java #спящий режим #jpa #entitymanager

Вопрос:

У меня есть такие объекты:

Шаблон:

 @Entity
@Table(name="TEMPLATE")
public class Template extends BaseEntityIdLong {


    private static final long serialVersionUID = 3208743090890588897L;

    @OneToMany(mappedBy = "template", orphanRemoval=true, cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, fetch=FetchType.EAGER)
    @JacksonXmlElementWrapper(useWrapping=false)
    private Set<TemplateControl> templatesSet;
  

TemplateControl:

 @Entity
@Table(name="TEMPLATE_CONTROLS")
public class TemplateControl extends BaseEntityIdLong implements Comparable<TemplateControl>{


    private static final long serialVersionUID = 161243586581385870L;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="template_id", referencedColumnName="id", nullable=true)
    private Template template;  

    @ManyToOne
    @JoinColumn(name="template_control_id", nullable=true)
    private TemplateControl parentControl;

    @OneToMany(mappedBy = "parentControl", orphanRemoval=true, cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.EAGER)
    @Fetch(FetchMode.SUBSELECT)
    @BatchSize(size = 10)
    private Set<TemplateControl> children = new LinkedHashSet<TemplateControl>();


    /** TemplateControl attributes */
    @OneToMany(mappedBy = "templateControls", orphanRemoval=true, cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.EAGER)
    @Fetch(FetchMode.SUBSELECT)

    @BatchSize(size = 10)
    private Set<ControlAttribute> controlAttributes;

    @Transient
    private int columnIndex;

    @Transient 
    private GuiAttributes attributes;
  

ControlAttribute:

 @Entity
@Table(name="CONTROL_ATTRIBUTE")
public class ControlAttribute extends BaseEntityIdLong {

    private static final long serialVersionUID = -1454089401068519858L;

    @ManyToOne//(fetch=FetchType.EAGER)
    @JoinColumn(name="template_controls_id", referencedColumnName="id", nullable=false)
    @NotNull
    private TemplateControl templateControls;
  

У меня есть шаблон, который содержит некоторые templateControls (например, компоненты area ), а в области у меня есть другие templateControl (например buttons ), моя проблема заключается в том, что я клонирую кнопку и добавляю ее в набор templateSet (обычно я устанавливаю его parentControl в null и свойство шаблона с используемым шаблоном) и удаляю оригинал из дочерних элементов. EntityManager.merge(template) Иногда удаляет templateControl и его ControlAttributes , но он должен его обновить. Иногда выдает эту ошибку:

 org.postgresql.util.PSQLException: ERROR: null value in column "template_controls_id" violates not-null constraint
  Detail: Failing row contains (17226, null).
  

Который исходит из controlAttribute, потому что его TemplateControl равен null, но я проверил в debug, и его TemplateControl не равен null, у него хороший объект. Любое предложение, чего мне не хватает?

UPDATE1:

Метод слияния:

 @PersistenceContext(unitName=PersistenceJPAConfig.BEAN_PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;

public T update(T entity) throws DAOException {
    LOGGER.debug("[DAO] Update entity: "   entity);
    try{
        Preconditions.checkNotNull(entity);

        return (T) entityManager.merge(entity);
    }catch(Exception e){
        LOGGER.error("[DAO] Error while updating entity: "   entity, e);
        throw new DAOException(e.getMessage(), e);
    }
}
  

Метод clone работает нормально, я проверил его, и коллеги тоже используют, я долго не думал, что это поможет, если я его опубликую.

Комментарии:

1. можете ли вы опубликовать код клонирования и слияния?

2. В ваших отношениях указано «orphanRemoval = true». Удаление сирот предназначено только для экземпляров, которые не могут существовать без своего родителя, поэтому, если они когда-либо будут удалены, они будут удалены автоматически. Я предполагаю, что это то, что происходит, основываясь на вашем утверждении «и я удаляю оригинал из дочерних элементов». Если нет, предоставьте более подробную информацию о том, что именно вы делаете, и ожидайте, что результат будет.

3. да, но я добавил его клон в набор шаблонов, например, я думаю, что он должен обновить его в базе данных