2012-12-28 42 views
1

使用:Glassfish 3.1.2,EclipseLink。刪除級聯失敗時JTA不回滾

我有以下三個類JPA模型:

@Entity public class Customer implements Serializable { 

@Id private Integer id; 

@OneToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval=true) 
private Person person; 

[...]

@Entity public class Person implements Serializable { 

@Id private Integer id; 

[...]

@Entity public class Request implements Serializable { 

@Id private Integer id; 

@ManyToOne private Person person; 

我試圖刪除客戶採用以下策略(使用CMT):

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
<persistence-unit name="MyPU" transaction-type="JTA"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    <properties> 
     <property name="eclipselink.ddl-generation" value="create-tables"/> 
     <property name="eclipselink.ddl-generation.output-mode" value="database"/> 

     <property name="eclipselink.logging.level" value="FINE"/> 
     <property name="eclipselink.logging.parameters" value="true"/> 
     <property name="eclipselink.logging.logger" value="DefaultLogger"/>     
     <property name="eclipselink.logging.timestamp" value="true"/> 
     <property name="eclipselink.logging.session" value="false"/> 
     <property name="eclipselink.logging.thread" value="false"/> 
    </properties> 
</persistence-unit> 

[...]

@PersistenceContext(unitName="MyPU") 
private EntityManager entityManager; 

@Resource private SessionContext context; 

[...]

public void delete(Entity object) { 

    try{ 

     object = this.getEntityManager().merge(object); 
     this.getEntityManager().remove(object); 

    } catch (Exception e){ 

     this.context.setRollbackOnly(); 
    } 
} 

客戶對象被附接到一個對象,它是附加到請求,del ete級聯失敗導致事務回滾,但客戶從數據庫中刪除。我收到以下錯誤:

INFO: [EL Fine]: 2012-12-28 10:53:38.1--Connection(27132168)--DELETE FROM CUSTOMER WHERE (ID = ?) 
bind => [97] 
INFO: [EL Fine]: 2012-12-28 10:53:38.125--Connection(27132168)--DELETE FROM PERSON WHERE (ID = ?) 
bind => [111] 
INFO: [EL Fine]: 2012-12-28 10:53:38.126--SELECT 1 
WARNING: DTX5014: Caught exception in beforeCompletion() callback: 
Local Exception Stack: 
INFO: [EL Warning]: 2012-12-28 10:53:38.127--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: org.postgresql.util.PSQLException: ERRO: atualização ou exclusão em tabela "person" viola restrição de chave estrangeira "fk_request_person_id" em "request" 
Detalhe: Chave (id)=(111) ainda é referenciada pela tabela "request". 
Error Code: 0 
Call: DELETE FROM PERSON WHERE (ID = ?) 
bind => [111] 
Query: DeleteObjectQuery(111) 
[...] 
SEVERE: javax.ejb.EJBException: Transaction aborted 
[...] 

那麼,如何取消客戶刪除級聯刪除失敗時?

+0

是您的數據庫連接設置爲自動提交,也許?如果沒有,請向我們展示您的交易邊界。 – sorencito

+0

這可能是問題所在。我使用** Oracle 10g **連接測試應用程序,並且**回滾工作**(我需要應用程序使用這兩個數據庫 - Oracle 10g和Postgres 8.4)。該事務處於無狀態Bean上,該BADARY是** JTA的默認**(需要)。有沒有辦法禁用Postgres 8.4(我使用)autocommit根據**這個鏈接**:_http://stackoverflow.com/questions/13837146/postgres-setting-autocommit-off-globally_。也許我必須使用一個bean管理的事務? – user1934440

+0

帶邊界我的意思是交易的開始和結束 - 無論如何,如果它與Oracle一起工作,問題是數據庫(連接)。請發佈連接設置。 – sorencito

回答

0

這裏有兩件事情可能會出錯。

  • 事務邊界未正確指定

也許由於這個原因,你的應用服務器不發出正確的BEGIN語句。這可以解釋Postgres有問題,而Oracle不會(它隱式地啓動事務)。確保您的服務方法使用正確的註釋。如果一切正常,或許

  • 數據源存在問題。

它是一個兼容JTA的數據源嗎?它是否使用Postgres的正確驅動程序?請發佈您的配置,以便我們可以退房。

我找到了一個有趣的鏈接,可以幫助你。它是關於Postgres的在自動提交模式下保持(使用雖然當春):

http://archives.postgresql.org/pgsql-jdbc/2007-07/msg00115.php

+0

使用* * defaultAutocommit = false **(如您在發佈的鏈接中所述)在Glassfish的JDBC連接池屬性上解決了此問題。我使用PostgreSQL 8.4.15和postgresql-8.4-703.jdbc4.jar驅動程序。 – user1934440

+0

好的,我會修改答案,以便讓更多讀者明白解決方案是什麼。你能說你使用了哪一類嗎?簡單的我們PoolableDatasource? – sorencito

+0

我使用一個簡單的類。 – user1934440