我有一個用戶實體:EntityManager.merge沒有做任何
@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版本和等於/哈希碼定義。
我有一個基礎的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>
我最近升級到2.3.2的EclipseLink和Spring 3.1,並從CGLIB代理轉換爲使用aspectJ for Spring的加載時織入,但是我沒有爲eclipselink配置LTW。
問題出在這個代碼中,這個代碼生活在一個Spring ApplicationListener中,參見注釋。
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只是設置一些字段並返回this
我敢肯定它是怎麼熬過這些代碼,因爲我得到登錄周圍的語句,我可以設置斷點,並通過它走。我的postgres日誌不顯示任何訪問postgres進行合併的流量。
我在其他地方保存其他東西沒有問題,包括用戶在更改密碼時在其他位置,我知道此代碼用於工作。這裏有什麼明顯的錯誤嗎?我是否錯誤地使用OpenEntityManagerInViewFilter?我是否需要在@Transactional方法中才能考慮管理實體?任何幫助表示讚賞。
更新 我嘗試了prajeesh建議的沖洗。這裏是代碼
@Transactional
public T merge(T entity)
{
entity = em.merge(entity);
em.flush();
return entity;
}
在com.bi.data
的一個類中。我有這個在我的春天應用程序配置文件
<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: 我恢復了我的變化,使加載時間編織,現在合併經過帶或不帶沖洗,但我還是不明白的問題是什麼LTW ...
看起來好像你有事務配置正確。也許包括你的persistence.xml,確保你使用的是RESOURCE_LOCAL。最好啓用日誌記錄以查看發生了什麼。 – James 2012-01-31 14:10:27
感謝詹姆斯的想法。下班後我會看看它。我很確定我們使用的是RESOURCE_LOCAL,因爲我們在tomcat中運行,所以從未做過JTA。 – digitaljoel 2012-01-31 15:48:24
您是否嘗試在@Transactional註釋中添加propagation = Propagation.REQUIRED? – 2013-08-23 15:13:01