我有一个用户实体:
- @Entity
- @Table( name = "bi_user" )
- @SequenceGenerator( name = "USER_SEQ_GEN",sequenceName = "USER_SEQUENCE" )
- public class User
- extends DataObjectAbstract<Long>
- {
- private static final long serialVersionUID = -7870157016168718980L;
- /**
- * key for this instance. Should be managed by JPA provider.
- */
- @Id
- @GeneratedValue( strategy = GenerationType.SEQUENCE,generator = "USER_SEQ_GEN" )
- private Long key;
- /**
- * Username the user will use to login. This should be an email address
- */
- @Column( nullable=false,unique=true)
- private String username;
- // etc. other columns and getters/setters
- }
其中DataObjectAbstract是一个简单的@MappedSuperClass,它具有jpa版本和equals / hashcode定义.
我有一个基本的dao类,看起来像这样
- public abstract class BaseDaoAbstract<T extends DataObject<K>,K extends Serializable>
- implements BaseDao<T,K>
- {
- @PersistenceContext
- private EntityManager em;
- /**
- * Save a new entity. If the entity has already been persisted,then merge
- * should be called instead.
- *
- * @param entity The transient entity to be saved.
- * @return The persisted transient entity.
- */
- @Transactional
- public T persist( T entity )
- {
- em.persist( entity );
- return entity;
- }
- /**
- * merge the changes in this detached object into the current persistent
- * context and write through to the database. This should be called to save
- * entities that already exist in the database.
- *
- * @param entity The entity to be merged
- * @return The merged entity.
- */
- @Transactional
- public T merge( T entity )
- {
- return em.merge( entity );
- }
- // other methods like persist,delete,refresh,findByKey that all delegate to em.
- }
我已经在web.xml中定义了OpenEntityManagerInView过滤器,如下所示
- <filter>
- <filter-name>openEntityManagerInViewFilter</filter-name>
- <filter-class>
- org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
- </filter-class>
- <init-param>
- <param-name>entityManagerfactorybeanName</param-name>
- <param-value>biEmf</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>openEntityManagerInViewFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
我最近升级到eclipselink 2.3.2和Spring 3.1,并从CGLIB代理转换为使用AspectJ for Spring的加载时间编织,但是我没有为eclipselink配置LTW.
问题出在这个代码中,它存在于SpringListener中,见注释.
- User user = userService.findByKey(userDetails.getKey());
- // THIS MERGE NEVER WRITES THROUGH TO THE DATABASE.
- // THIS DOESN'T WORK AS PERSIST EITHER
- user = userService.merge( user.loginSuccess() );
user.loginSuccess只是设置一些字段并返回这个我确定它正在通过代码,因为我收到日志语句,我可以设置一个断点并通过它.我的postgres日志没有显示任何流量到postgres合并.
我保存所有地方的其他东西没有问题,包括用户在另一个位置,当他们更改密码,我知道这个代码以前工作.这里有什么明显的不好吗?我使用OpenEntityManagerInViewFilter不正确吗?我应该使用@Transactional方法,以便实体被认为是管理的?任何帮助是赞赏.
更新
我尝试了由prajeesh建议的冲水.这是代码
- @Transactional
- public T merge( T entity )
- {
- entity = em.merge( entity );
- em.flush();
- return entity;
- }
在com.bi.data的一个类中.我有这个在我的春天app配置文件
- <context:component-scan base-package="com.bi.controller,com.bi.data,com.bi.web" />
在我的春天配置我有
- <context:load-time-weaver/>
- <tx:annotation-driven mode="aspectj"/>
一个aop.xml如下所示:
- <aspectj>
- <weaver>
- <!-- only weave classes in our application-specific packages -->
- <include within="com.bi..*"/>
- </weaver>
- </aspectj>
我得到了
- javax.persistence.TransactionrequiredException:
- Exception Description: No transaction is currently active
所以有些东西显然配置错误,但是什么?
更新2:
我恢复了我的更改以启用加载时间编织,现在合并通过或不使用flush,但我仍然不明白LTW的问题是什么…
解决方法
在em.merge()之后尝试em.flush().有时,EntityManager只是稍后保留更新以进行更新.