Слияние Hibernate теряет данные

Я получаю странную проблему с Hibernate и merge.

структура рассматриваемых классов выглядит следующим образом:

Project --> CaseWorkerA --|> CaseWorker --|> User

Итак, в основном у меня есть класс проекта, который содержит ссылку на CaseWorkerA, который является подклассом CaseWorker, который снова является подклассом User.

в коде:

public class Project {
    [...]
    private CaseWorkerA caseWorkerA;

    @ManyToOne(fetch = FetchType.EAGER)
    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST,
           org.hibernate.annotations.CascadeType.REFRESH, org.hibernate.annotations.CascadeType.MERGE })
    @JoinColumn(name = "CaseWorker_A")
    public CaseWorkerA getCaseWorkerA() {
        return caseWorkerA;
    }
}

тогда у нас есть пользовательская иерархия:

public class User {
    [...]
}

public class CaseWorker extends User {
    private CaseWorkerStatus status;

    @Enumerated(EnumType.STRING)
    public CaseWorkerStatus getStatus() {
        return status;
    }
    [...]
}

public class CaseWorkerA extends CaseWorker {
    [...]
}

тогда в Dao-классе есть метод для хранения проект:

public class ProjectDao {
    [...]
    public Project saveUpdateProject(final Project project) {
        if (project.getId() == null) {
            getSession(false).save(project);
        } else {
            project = (Project) getSession(false).merge(project);
        }
        getHibernateTemplate().flush();
        return project;
    }
}

теперь проблема заключается в следующем:

Dao-метод получает проект, который существует в базе данных. Этот проект связан с CaseWorkerA, который имеет статус CaseWorkerStatus.ACTIVE (как в базе данных, так и в объекте incomming). Но после слияния статус соцработника становится нулевым.

Я действительно не понимаю, как это возможно, так как значение одинаково в базе данных, как и в объекте для хранения, я бы рассчитываем, что после слияния.

(в базе данных нет триггеров для этого поля..)

(Я попытаюсь изменить dao-метод, чтобы использовать saveOrUpdate вместо этого, но даже если это исправит проблему, я все равно очень хотел бы знать, что вызвало ее в первую очередь).

обновление:

так что я возился с отладчиком и обнаружил следующее: Когда я спросил сессии для соцработника в вопрос, оказалось с его набором полей состояния (на самом деле возвращаемый объект был именно тем, который был подключен к проекту).

делаем saveOrUpdate, а потом сделать, в результате соцработник со статусом-поля. Таким образом, это, похоже, проблема с методом merge..

1 ответов


удалось это выяснить, оказалось, что был второй путь от проекта к пользователю (lastChangedBy), где кто-то решил поставить Каскад по какой-то странной причине. Поэтому, когда человек, который в последний раз изменял проект, был соц.работником, lastChangedBy ссылался на него как на пользователя, который ничего не знает о статусе, поэтому он был сохранен как null.

код:

public class Project {
    private User changedBy;

    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST,
               org.hibernate.annotations.CascadeType.REFRESH, org.hibernate.annotations.CascadeType.MERGE })
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "changed_by")
    public User getChangedBy() {
        return this.changedBy;
    }
    [...]
}

пользователь, который был установлен как changedBy, был извлечен из базы данных вот так:

public class UserDao {
    public User getUser(final String userName) {
        return (User) getSession(false).createQuery("from User u where u.loginName = :username").setParameter("username", userName).uniqueResult();
    }
}

Appearantly, даже если пользователь одного конца до получения это-соцработник, поля, имеющие отношение к соцработник не получен..

в любом случае, удалил каскад uneccesary, и все хорошо :)