2012-01-31 67 views
10

我有一個用戶實體: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 ...

+0

看起來好像你有事務配置正確。也許包括你的persistence.xml,確保你使用的是RESOURCE_LOCAL。最好啓用日誌記錄以查看發生了什麼。 – James 2012-01-31 14:10:27

+0

感謝詹姆斯的想法。下班後我會看看它。我很確定我們使用的是RESOURCE_LOCAL,因爲我們在tomcat中運行,所以從未做過JTA。 – digitaljoel 2012-01-31 15:48:24

+0

您是否嘗試在@Transactional註釋中添加propagation = Propagation.REQUIRED? – 2013-08-23 15:13:01

回答

12

也試過em.flush()em.merge()。有時EntityManager只是保留稍後更新的更改。

+1

它沒有爲我工作 – vicky 2015-11-03 12:25:06

1

哪裏transaction.begin()transaction.end()方法呢?在RESOURCE_LOCAL如果在Spring配置文件中的以下行,你應該管理的事務,而不是應用程序...

+0

另一種可能性是交易是隻讀的。 – okwap 2016-06-30 06:51:19

0

檢查: 這使得@Transactional註解的支持,同時也確保模式=」代理「,not mode =」aspectj「設置爲

+0

該鏈接不再有效。 – 2017-06-26 07:47:26

2

EntityManager autocommit爲false。請使用下面的交易;

EntityManager em = null; 
EntityTransaction t = null; 
try { 
    em = emf.createEntityManager(); 
    t = em.getTransaction(); 
    t.begin(); 
    em.merge(myTestObject); 
    t.commit(); 
} catch (Exception e) { 
    t.rollback(); 
    throw new RuntimeException(e.getMessage()); 
}finally{ 
    if(em != null) 
     em.close(); 
} 
+0

我使用jpa,它不允許em.getTransaction(), – vicky 2015-11-03 12:25:33

+0

有時JPA無法在路徑中找到persistence.xml文件。你的persistence.xml路徑在哪裏?如果您的em爲空,請將persistence.xml移至src/main/java/META-INF/persistence.xml – ethemsulan 2015-11-04 11:11:23