我们在应用程序中使用的是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的定义也相同。
还有没有其他人遇到过这个问题并找到了解决方案?