Мы используем Hibernate 3.3.2 / Spring 3.0.5 в нашем приложении, и один из серверных модулей все еще использует старые классы HibernateTemplate
/ HibernateDaoSupport
.Я пытался удалить их, так как я должен реализовать нашу собственную логику транзакций в этом модуле.Проблема в том, что если я получаю прямой доступ к сеансу вместо использования HibernateTemplate, Hibernate действует так, как будто все сущности имеют аннотацию @Immutable
: я могу создавать новые записи в базе данных и удалять эти или старые, но я больше не могу обновлять существующие записи.
Я сузил проблему до DefaultFlushEventListener.onFlush
, где source.getPersistenceContext().hasNonReadOnlyEntities()
всегда возвращает false
в этом случае, но я пока не мог выяснить, почему этот флаг установлен неправильно.Я также убедился, что ни одна из сущностей на самом деле не помечена как @Immutable
или активно настроена на чтение только в любом месте, используя Query.setReadOnly
или Session.setReadOnly
.
Хуже, установка readonly=false
в любом месте также не имеет никакого эффекта.сущность остается неизменной.
В других наших серверных модулях мы никогда не использовали HibernateTemplate
/ HibernateDaoSupport
, и они прекрасно работают со всеми операциями CRUD.
Этот код используетстарые классы Hibernate:
@Transactional(rollbackFor = { Exception.class })
public class GenericHibernateDAO<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDAO <T, PK>
{
@Override
public Serializable create(final T instance)
{
return this.getHibernateTemplate().save(instance);
}
@Override
public void update(final T instance)
{
this.getHibernateTemplate().saveOrUpdate(instance);
}
@Override
public T findById(final Class <T> clazz, final PK id)
{
return this.getHibernateTemplate().get(clazz, id);
}
...
}
Вот как я изменил его и как он работает в других наших модулях:
@Transactional(rollbackFor = { Exception.class })
public class GenericHibernateDAO<T, PK extends Serializable> implements GenericDAO <T, PK>
{
protected SessionFactory sessionFactory;
public SessionFactory getSessionFactory()
{
return this.sessionFactory;
}
public void setSessionFactory(final SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public Session getSession()
{
return SessionFactoryUtils.getSession(this.sessionFactory, true);
}
@Override
public Serializable create(final T instance)
{
return this.getSession().save(instance);
}
@Override
public void update(final T instance)
{
this.getSession().saveOrUpdate(instance);
}
@Override
public T findById(final Class <T> clazz, final PK id)
{
return (T) this.getSession().get(clazz, id);
}
...
}
Определение производного класса DAO:
public class RepositoryFolderHibernateDAO extends GenericHibernateDAO <RepositoryFolder, Long> implements RepositoryFolderDAO
Определение сущности:
@Entity
@javax.persistence.Table(name = "repositoryfolder")
public class RepositoryFolder
{
@Id
@GeneratedValue
private long id;
@Column(name = "repository_id", nullable = false)
private long repositoryId = 1L;
@Column(name = "parent_id", nullable = true)
private Long parent;
@Column(length = 255, nullable = false)
private String name;
@Column(length = 255, nullable = true)
private String description;
@Cascade(value =
{ org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "id.folderId")
private Set <MandatorFolderRight> mandatorFolderRights = new HashSet <MandatorFolderRight>();
public RepositoryFolder()
{
super();
}
... more c'tors and getters/setters
}
При использовании HibernateDao
+ HibernateTemplate
все обновления выполняются, но без них игнорируются и просто работают операции создания и удаления.Я искал несколько дней, но не мог найти причину этого странного поведения.Определения bean-компонентов также одинаковы в обоих случаях.
Кто-нибудь еще сталкивался с этой проблемой и нашел решение?