完整性约束只是违反了,当我提交事务 [英] Integrity constraint violated just when I commit the transaction

查看:421
本文介绍了完整性约束只是违反了,当我提交事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Hibernate 4.0最终和ojdbc6发展自己的Web应用程序。一切都只是当我尝试插入一个新的父/子关系确定。首先,这些都是实体:

  @Entity
@Table(NAME =雇员)
公共类员工实现Serializable,Cloneable的{
    @ID
    @SequenceGenerator(NAME =序列,sequenceName =P_SEQ)
    @GeneratedValue(发电机=序列)
    @Column(NAME =ID_EMPLOYEE)
    私人长期idEmployee;
    ......
    @OneToMany(的cascade = CascadeType.ALL,取= FetchType.EAGER,的mappedBy =雇员,orphanRemoval = TRUE)
    @Fetch(FetchMode.SELECT)
    @BatchSize(大小= 10)
    私人设置<地址>地址;
    ......
}@实体
@Table(NAME =地址)
公共类地址实现Serializable,Cloneable的,可比{
    @ID
    @SequenceGenerator(NAME =序列,sequenceName =P_SEQ)
    @GeneratedValue(发电机=序列)
    @Column(NAME =ID_ADDRESS)
    私人长期idAddress;    @ManyToOne(取= FetchType.LAZY)
    @JoinColumn(NAME =ID_EMPLOYEE)
    私人雇员雇员;
    .......
}

让我们来看看这两种情况:


  1. 的雇员已经存在,我尝试将新地址添加到它 - >
    它工作正常。

  2. 的雇员还不存在,我尝试创建一个新的。二diferent情况:结果

    • 一)我只插入一个员工(没有地址) - >它正常工作

    • 二)我插入和员工及其地址 - > 它失败。我不得不说,这一定是一个原子事务。我的意思是,我需要一次创建(保存)为它的员工和一个地址。


这是事务处理程序:

 公共静态无效保存(员工员工)抛出HibernateException的,异常{
    会话的会话= HibernateUtil.getCurrentSession();
    session.beginTransaction();
    尝试{
        session.saveOrUpdate(员工);
    }赶上(例外前){
        session.refresh(员工);
        HibernateUtil.closeSession();
        扔恩;
    }
    HibernateUtil.commitTransaction();
}
公共静态无效commitTransaction()抛出异常{
    交易TX =了getSessionFactory()的getCurrentSession()getTransaction()。
    尝试{
        如果(TX = NULL&放大器;!&安培;!tx.wasCommitted()及和放大器;!tx.wasRolledBack()){
            tx.commit();
        }
    }赶上(例外前){
        tx.rollback();
        扔恩;
    } {最后
        closeSession();
    }
}

你可以想像,在2.B情况下是一个我很担心。我调试的交易,这是我得到的,当我调用save()方法(这是在DAO类):


  1. session.saveOrUpdate(员工)方式成功执行(我可以检查所保存的员工有一个地址)。此外,它的 idEmployee 已正确设置(从序列取)和地址绑定到员工,并具有有效的 idAddress (从序列取,以及)。

  2. 的执行过程中的 commitTransaction()方式,我得到一个 org.hibernate.exception.ConstraintViolationException ,虽然两者 idEmployee idAddress 已previously正确设置。

总之,异常只是在提交过程中走出来。这就像如果就此开始commiting子(地址),而不是父(员工)。

我是什么做错了吗?有谁能够帮助我?先谢谢了。

更新。以上,可以看到参与该问题的两个班的主要部分。现在,在这里你是叫他们除了异常的痕迹的方法。他们是在他们被调用的顺序。

属于该DataBacking类:

 公共无效保存(ActionEvent的事件){
    尝试{
        EmployeeDAO.save(selectedEmployee);
        新员工(); //重新设置员工及其藏品
    }赶上(ConstraintViolationException前){
        Utilities.addFacesMessage(FacesMessage.SEVERITY_WARN,ex.getMessage(),);
    }赶上(例外前){
        Utilities.log(错误,ex.getCause()的toString());
        Utilities.addFacesMessage(FacesMessage.SEVERITY_WARN,ex.getMessage(),);
    }
}

属于该Empl​​oyeeDAO类:

 公共静态无效保存(员工员工)抛出HibernateException的,异常{
    会话的会话= HibernateUtil.getCurrentSession();
    session.beginTransaction();
    尝试{
        session.saveOrUpdate(员工);
    }赶上(例外前){
        session.refresh(员工);
        HibernateUtil.closeSession();
        扔恩;
    }
    HibernateUtil.commitTransaction();
}

属于HibernateUtil类:

 公共静态无效commitTransaction()抛出异常{
    交易TX =了getSessionFactory()的getCurrentSession()getTransaction()。
    尝试{
        如果(TX = NULL&放大器;!&安培;!tx.wasCommitted()及和放大器;!tx.wasRolledBack()){
            tx.commit();
        }
    }赶上(例外前){
        tx.rollback();
        扔恩;
    } {最后
        closeSession();
    }
}

右键后,该Empl​​oyeeDAO.save()方法调用session.SaveOrUpdate(员工),我得到以下跟踪:

  2013年3月12日07:22:55958 [DEBUG,org.hibernate.internal.SessionImpl]开于时间戳会议:13630693759
2013年3月12日07:22:57584 [DEBUG,org.hibernate.engine.transaction.spi.AbstractTransactionImpl]开始
2013年3月12日07:22:57585 [DEBUG,org.hibernate.engine.jdbc.internal.LogicalConnectionImpl]获取JDBC连接
2013年3月12日07:22:57586 [DEBUG,org.hibernate.engine.jdbc.internal.LogicalConnectionImpl]获得JDBC连接
2013年3月12日07:22:57587 [DEBUG,org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction]初始状态自动提交:真
2013年3月12日07:22:57587 [DEBUG,org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction]禁用自动提交
2013年3月12日07:23:00285 [DEBUG,org.hibernate.SQL]
    选择
        P_SEQ.nextval
    从
        双
2013年3月12日07:23:00361 [DEBUG,org.hibernate.id.SequenceGenerator]序列标识符生成:BasicHolder [java.lang.Long中的[5665]
2013年3月12日07:23:00365 [DEBUG,org.hibernate.event.internal.AbstractSaveEventListener]生成的标识符:5665,使用策略:org.hibernate.id.SequenceGenerator
2013年3月12日07:23:00411 [DEBUG,org.hibernate.SQL]
    选择
        P_SEQ.nextval
    从
        双
2013年3月12日07:23:00417 [DEBUG,org.hibernate.id.SequenceGenerator]序列标识符生成:BasicHolder [java.lang.Long中的[5666]
2013年3月12日07:23:00421 [DEBUG,org.hibernate.event.internal.AbstractSaveEventListener]生成的标识符:5666,使用策略:org.hibernate.id.SequenceGenerator

和后提交已被调用:

  2013年3月12日07:24:53288 [DEBUG,org.hibernate.engine.transaction.spi.AbstractTransactionImpl]犯
2013年3月12日07:24:53336 [DEBUG,org.hibernate.event.internal.AbstractFlushingEventListener]处理冲水时级联
2013年3月12日07:24:53343 [DEBUG,org.hibernate.event.internal.AbstractFlushingEventListener]脏检查集合
2013年3月12日07:24:53403 [DEBUG,org.hibernate.engine.internal.Collections]集合发现:[org.svq.pol.gesper.bean.Employee.addresses#5665]为:[<未引用&GT ](初始化)
2013年3月12日07:24:53439 [DEBUG,org.hibernate.event.internal.AbstractFlushingEventListener]脸涨得通红:2插入,更新0,0删节2个对象
2013年3月12日07:24:53440 [DEBUG,org.hibernate.event.internal.AbstractFlushingEventListener]脸涨得通红:1(重新)创作,0更新,0清除至1集
2013年3月12日07:24:53453 [DEBUG,org.hibernate.internal.util.EntityPrinter]清单实体:
2013年3月12日07:24:53454 [DEBUG,org.hibernate.internal.util.EntityPrinter] org.svq.pol.gesper.bean.Address {地址= fasdf,PC =,=城市fadsf,idAddress = 5666,运算符= XXXXX,全省=,= telef2,movDate =周二3月12日7时21分15秒CET 2013年,telef1 =,=员工#org.svq.pol.gesper.bean.Employee 5665,版本= 0}
2013年3月12日07:24:53456 [DEBUG,org.hibernate.internal.util.EntityPrinter] org.svq.pol.gesper.bean.Employee {姓= fadsf,用户= NULL,DOB =周二00年1月1日: 00:00 CET 1980年,地址= [org.svq.pol.gesper.bean.Address#5666],POB = fadsf,运算符= XXXXX,movDate =周二3月12日7时21分15秒CET 2013,版本= 0,名称= fasdf,性别= H,idEmployee = 5665,ID = 12345678}
2013年3月12日07:24:53572 [DEBUG,org.hibernate.SQL]
    插
    成
        雇员
    (姓,身份证,MOV_DATE,出生日期,性别,POB,运营商,用户,版本,ID_EMPLOYEE)
    值
        (?,?,?,?,?,?,?,?,?,?)
2013年3月12日07:24:53793 [DEBUG,org.hibernate.SQL]
    插
    成
        地址
    (PC,地址,MOV_DATE,运营商,ID_EMPLOYEE,市,省,telef_1,telef_2,版本,ID_ADDRESS)
    值
        (?,?,?,?,?,?,?,?,?,?,?)
2013年3月12日07:24:53943 [DEBUG,org.hibernate.engine.jdbc.spi.SqlExceptionHelper] ORA-02291:诚信约束(PERPLADM.ADDRESS_EMPLOYEE_FK)侵犯 - 父键未找到
 [N / A]
java.sql.SQLIntegrityConstraintViolationException:ORA-02291:诚信约束(PERPLADM.ADDRESS_EMPLOYEE_FK)侵犯 - 父键未找到    在oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
    在oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    在oracle.jdbc.driver.T4C8Oall.pr​​ocessError(T4C8Oall.java:879)
    在oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
    在oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
    在oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    在oracle.jdbc.driver.T4C preparedStatement.doOall8(T4C preparedStatement.java:207)
    在oracle.jdbc.driver.T4C preparedStatement.executeForRows(T4C preparedStatement.java:1044)
    在oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
    在oracle.jdbc.driver.Oracle preparedStatement.executeInternal(甲骨文preparedStatement.java:3584)
    在oracle.jdbc.driver.Oracle preparedStatement.executeUpdate(甲骨文preparedStatement.java:3665)
    在oracle.jdbc.driver.Oracle$p$pparedStatementWrapper.executeUpdate(Oracle$p$pparedStatementWrapper.java:1352)
    在org.apache.tomcat.dbcp.dbcp.Delegating$p$pparedStatement.executeUpdate(Delegating$p$pparedStatement.java:105)
    在org.apache.tomcat.dbcp.dbcp.Delegating$p$pparedStatement.executeUpdate(Delegating$p$pparedStatement.java:105)
    在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
    在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在java.lang.reflect.Method.invoke(Method.java:601)
    在org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    在org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    在$ Proxy46.executeUpdate(来源不明)
    在org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
    在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2849)
    在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3290)
    在org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
    在org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:273)
    在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:265)
    在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
    在org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:323)
    在org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    在org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
    在org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
    在org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    在org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    在org.svq.pol.gesper.utility.HibernateUtil.commitTransaction(HibernateUtil.java:57)
    在org.svq.pol.gesper.dao.EmployeeDAO.save(EmployeeDAO.java:110)
    在org.svq.pol.gesper.backing.DataBacking.save(DataBacking.java:498)
    在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
    在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在java.lang.reflect.Method.invoke(Method.java:601)
    在org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    在org.apache.el.MethodEx pressionImpl.invoke(MethodEx pressionImpl.java:278)
    在com.sun.faces.facelets.el.TagMethodEx pression.invoke(TagMethodEx pression.java:105)
    在javax.faces.event.MethodEx$p$pssionActionListener.processAction(MethodEx$p$pssionActionListener.java:148)
    在javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    在javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
    在javax.faces.component.UICommand.broadcast(UICommand.java:300)
    在javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    在javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    在com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    在com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    在com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    在javax.faces.w​​ebapp.FacesServlet.service(FacesServlet.java:409)
    在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    在org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    在org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:515)
    在org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:302)
    在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:603)
    在java.lang.Thread.run(Thread.java:722)
2013年3月12日07:24:54027 [WARN,or​​g.hibernate.engine.jdbc.spi.SqlExceptionHelper] SQL错误:2291,​​SQLSTATE:23000
2013年3月12日07:24:54027 [错误,org.hibernate.engine.jdbc.spi.SqlExceptionHelper] ORA-02291:诚信约束(PERPLADM.ADDRESS_EMPLOYEE_FK)侵犯 - 父键未找到


解决方案

在几天为此而努力,我终于发现了什么问题是,很明显,该解决方案。据我所知,上面显示的映射是正确的(至少,应用程序工作正常)。唯一的问题是在数据库中,在那里有用于插入该序列的触发器。这样一来,每次我试图插入雇员(和它的地址),休眠给了我两张序列号(一个用于家长和另一个孩子),这是正确设置。然而,在做承诺的precise时刻,甲骨文给了我两个序列号,而这个时间设置不正确,我的意思是,外键不匹配父的主键。

不过,正如我需要触发器,我要做一个步骤:我不得不修改这些的人,使他们检查是否:new.ID NULL 与否。如果是,则意味着触发已经从休眠(即其他应用程序)外触发,因此我采取了NEXTVAL从序列,否则我离开这个来自休眠的价值。

I'm using Hibernate 4.0 Final and ojdbc6 to develop my web application. Everything is ok except when I try to insert a new parent/child relationship. First of all, these are the entities:

@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable, Cloneable {
    @Id
    @SequenceGenerator(name = "seq", sequenceName = "P_SEQ")
    @GeneratedValue(generator = "seq")
    @Column(name = "ID_EMPLOYEE")
    private long idEmployee;
    ......
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "employee", orphanRemoval = true)
    @Fetch(FetchMode.SELECT)
    @BatchSize(size = 10)
    private Set<Address> addresses;
    ......
}

@Entity
@Table(name = "ADDRESS")
public class Address implements Serializable, Cloneable, Comparable {    
    @Id
    @SequenceGenerator(name = "seq", sequenceName = "P_SEQ")
    @GeneratedValue(generator = "seq")
    @Column(name = "ID_ADDRESS")
    private long idAddress;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_EMPLOYEE")
    private Employee employee;
    .......
}

Let's see these two scenarios:

  1. An employee already exists and I try to add a new address to it --> It works properly.
  2. An employee doesn't exist yet and I try to create a new one. Two diferent cases:
    • a) I only insert an employee (with no address) --> It works properly.
    • b) I insert and employee and its address --> It fails. I have to say that this must be an atomic transaction. I mean, I need to create (save) an employee and one address for it at once.

This is the transaction handler:

public static void save(Employee employee) throws HibernateException, Exception {
    Session session = HibernateUtil.getCurrentSession();
    session.beginTransaction();
    try {
        session.saveOrUpdate(employee);
    } catch (Exception ex) {
        session.refresh(employee);
        HibernateUtil.closeSession();
        throw ex;
    }
    HibernateUtil.commitTransaction();
}
public static void commitTransaction() throws Exception {
    Transaction tx = getSessionFactory().getCurrentSession().getTransaction();
    try {
        if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
            tx.commit();
        }
    } catch (Exception ex) {
        tx.rollback();
        throw ex;
    } finally {
        closeSession();
    }
}

As you can imagine, the 2.b case is the one I'm concerned about. I've debugged the transaction and this is what I get when I call the save() method (which is in a DAO class):

  1. The session.saveOrUpdate(employee) method executes successfully (I can check that the saved employee has an address). Besides, its idEmployee is properly set (taken from the sequence) and the address is binded to the employee and has a valid idAddress (taken from the sequence, as well).
  2. During the execution of the commitTransaction() method I get an org.hibernate.exception.ConstraintViolationException, although both idEmployee and idAddress has been previously properly set.

In short, the Exception come out just during the commit process. It's like if this began commiting the child (address) instead the parent (employee).

What am I doing wrong? Can anybody help me? Thanks in advance.

UPDATED. Above, you can see the main parts of the two classes involved in the problem. Now, here you are the methods that call them besides the trace of exception. They are in the order they are called.

Belonging to the DataBacking class:

public void save(ActionEvent event) {
    try {
        EmployeeDAO.save(selectedEmployee);
        newEmployee();  //reset the employee and its collections
    } catch (ConstraintViolationException ex) {
        Utilities.addFacesMessage(FacesMessage.SEVERITY_WARN, ex.getMessage(), "");
    } catch (Exception ex) {
        Utilities.log("error", ex.getCause().toString());
        Utilities.addFacesMessage(FacesMessage.SEVERITY_WARN, ex.getMessage(), "");
    }
}

Belonging to the EmployeeDAO class:

public static void save(Employee employee) throws HibernateException, Exception {
    Session session = HibernateUtil.getCurrentSession();
    session.beginTransaction();
    try {
        session.saveOrUpdate(employee);
    } catch (Exception ex) {
        session.refresh(employee);
        HibernateUtil.closeSession();
        throw ex;
    }
    HibernateUtil.commitTransaction();
}

Belonging to the HibernateUtil class:

public static void commitTransaction() throws Exception {
    Transaction tx = getSessionFactory().getCurrentSession().getTransaction();
    try {
        if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
            tx.commit();
        }
    } catch (Exception ex) {
        tx.rollback();
        throw ex;
    } finally {
        closeSession();
    }
}

Right after that the EmployeeDAO.save() method calls to session.SaveOrUpdate(employee), I get the following trace:

2013-03-12 07:22:55,958 [DEBUG, org.hibernate.internal.SessionImpl] Opened session at timestamp: 13630693759 
2013-03-12 07:22:57,584 [DEBUG, org.hibernate.engine.transaction.spi.AbstractTransactionImpl] begin 
2013-03-12 07:22:57,585 [DEBUG, org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] Obtaining JDBC connection 
2013-03-12 07:22:57,586 [DEBUG, org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] Obtained JDBC connection 
2013-03-12 07:22:57,587 [DEBUG, org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction] initial autocommit status: true 
2013-03-12 07:22:57,587 [DEBUG, org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction] disabling autocommit 
2013-03-12 07:23:00,285 [DEBUG, org.hibernate.SQL] 
    select
        P_SEQ.nextval 
    from
        dual 
2013-03-12 07:23:00,361 [DEBUG, org.hibernate.id.SequenceGenerator] Sequence identifier generated: BasicHolder[java.lang.Long[5665]] 
2013-03-12 07:23:00,365 [DEBUG, org.hibernate.event.internal.AbstractSaveEventListener] Generated identifier: 5665, using strategy: org.hibernate.id.SequenceGenerator 
2013-03-12 07:23:00,411 [DEBUG, org.hibernate.SQL] 
    select
        P_SEQ.nextval 
    from
        dual 
2013-03-12 07:23:00,417 [DEBUG, org.hibernate.id.SequenceGenerator] Sequence identifier generated: BasicHolder[java.lang.Long[5666]] 
2013-03-12 07:23:00,421 [DEBUG, org.hibernate.event.internal.AbstractSaveEventListener] Generated identifier: 5666, using strategy: org.hibernate.id.SequenceGenerator 

And after the commit has been invoked:

2013-03-12 07:24:53,288 [DEBUG, org.hibernate.engine.transaction.spi.AbstractTransactionImpl] committing 
2013-03-12 07:24:53,336 [DEBUG, org.hibernate.event.internal.AbstractFlushingEventListener] Processing flush-time cascades 
2013-03-12 07:24:53,343 [DEBUG, org.hibernate.event.internal.AbstractFlushingEventListener] Dirty checking collections 
2013-03-12 07:24:53,403 [DEBUG, org.hibernate.engine.internal.Collections] Collection found: [org.svq.pol.gesper.bean.Employee.addresses#5665], was: [<unreferenced>] (initialized) 
2013-03-12 07:24:53,439 [DEBUG, org.hibernate.event.internal.AbstractFlushingEventListener] Flushed: 2 insertions, 0 updates, 0 deletions to 2 objects 
2013-03-12 07:24:53,440 [DEBUG, org.hibernate.event.internal.AbstractFlushingEventListener] Flushed: 1 (re)creations, 0 updates, 0 removals to 1 collections 
2013-03-12 07:24:53,453 [DEBUG, org.hibernate.internal.util.EntityPrinter] Listing entities: 
2013-03-12 07:24:53,454 [DEBUG, org.hibernate.internal.util.EntityPrinter] org.svq.pol.gesper.bean.Address{address=fasdf, pc=, city=fadsf, idAddress=5666, operator=xxxxx, province=, telef2=, movDate=Tue Mar 12 07:21:15 CET 2013, telef1=, employee=org.svq.pol.gesper.bean.Employee#5665, version=0} 
2013-03-12 07:24:53,456 [DEBUG, org.hibernate.internal.util.EntityPrinter] org.svq.pol.gesper.bean.Employee{surname=fadsf, user=null, dob=Tue Jan 01 00:00:00 CET 1980, address=[org.svq.pol.gesper.bean.Address#5666], pob=fadsf, operator=xxxxx, movDate=Tue Mar 12 07:21:15 CET 2013, version=0, name=fasdf, gender=H, idEmployee=5665, id=12345678} 
2013-03-12 07:24:53,572 [DEBUG, org.hibernate.SQL] 
    insert 
    into
        EMPLOYEE    
    (SURNAME, ID, MOV_DATE, DOB, GENDER, POB, OPERATOR, USER, VERSION, ID_EMPLOYEE)
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
2013-03-12 07:24:53,793 [DEBUG, org.hibernate.SQL] 
    insert 
    into
        ADDRESS
    (pc, address, MOV_DATE, OPERATOR, ID_EMPLOYEE, city, province, telef_1, telef_2, version, ID_ADDRESS)        
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
2013-03-12 07:24:53,943 [DEBUG, org.hibernate.engine.jdbc.spi.SqlExceptionHelper] ORA-02291: integrity constraint (PERPLADM.ADDRESS_EMPLOYEE_FK) violated - parent key not found
 [n/a] 
java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (PERPLADM.ADDRESS_EMPLOYEE_FK) violated - parent key not found

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3665)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1352)
    at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at $Proxy46.executeUpdate(Unknown Source)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2849)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3290)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:273)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:265)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:323)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.svq.pol.gesper.utility.HibernateUtil.commitTransaction(HibernateUtil.java:57)
    at org.svq.pol.gesper.dao.EmployeeDAO.save(EmployeeDAO.java:110)
    at org.svq.pol.gesper.backing.DataBacking.save(DataBacking.java:498)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:148)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
2013-03-12 07:24:54,027 [WARN, org.hibernate.engine.jdbc.spi.SqlExceptionHelper] SQL Error: 2291, SQLState: 23000 
2013-03-12 07:24:54,027 [ERROR, org.hibernate.engine.jdbc.spi.SqlExceptionHelper] ORA-02291: integrity constraint (PERPLADM.ADDRESS_EMPLOYEE_FK) violated - parent key not found

解决方案

After few days struggling with this, I eventually found what the problem was and, obviously, the solution. As far as I know, the mapping shown above is correct (at least, the application works properly). The only problem was in the database, where there was a trigger for inserting the sequence. This way, everytime I tried to insert an employee (and its address), Hibernate gave me two sequence numbers (one for the parent and another for the child), which were correctly set. However, at the precise moment of doing the commit, Oracle gave me two more sequence numbers, and this time incorrectly set, I mean, the foreign key didn't match the parent's primary key.

But as I need triggers, I have to do one more step: I have to modify these ones so they check whether the :new.ID value is NULL or not. If it is, it means that the trigger has been triggered from outside Hibernate (i.e. another application), and therefore I take the nextval from the sequence, otherwise I leave the value that comes from Hibernate.

这篇关于完整性约束只是违反了,当我提交事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆