当前位置: 首页 > 知识库问答 >
问题:

提交事务时违反了完整性约束

公西天逸
2023-03-14

我正在使用Hibernate 4.0最终版和ojdbc6来开发我的网络应用程序。一切都好,除了当我试图插入一个新的父母/孩子的关系。首先,这些是实体:

@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;
    .......
}

让我们看看这两个场景:

  • 员工已存在,我尝试向其添加新地址--

这是事务处理程序

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();
    }
}

你可以想象,2.b的案子是我关心的。我已经调试了事务,这是我调用保存()方法(在DAO类中)时得到的:

  1. 会议结束了。saveOrUpdate(employee)方法成功执行(我可以检查保存的员工是否有地址)。此外,其ideemployee已正确设置(取自序列),地址绑定到员工,并具有有效的idAddress(取自序列)
  2. 在commitTransaction()方法的执行过程中,我得到一个org。冬眠例外ConstraintViolationException,尽管先前已正确设置了IdeEmployeeidAddress

简而言之,异常仅在提交过程中出现。这就像是开始提交子对象(地址)而不是父对象(员工)。

我做错了什么?有人能帮我吗?提前谢谢。

更新。在上面,您可以看到问题涉及的两个类的主要部分。现在,除了异常跟踪之外,还有调用它们的方法。它们是按照它们被称为的顺序排列的。

属于数据备份类:

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(), "");
    }
}

属于EmployeeDAO类:

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();
}

属于HibernateUtil类:

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();
    }
}

紧接着,员工DAO.保存()方法调用会话。SaveOrUpdate(员工),我得到以下跟踪:

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 

调用提交后:

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

共有1个答案

钮鸿煊
2023-03-14

经过几天的挣扎,我最终找到了问题所在,显然找到了解决方案。据我所知,上面显示的映射是正确的(至少,应用程序正常工作)。唯一的问题是在数据库中,那里有一个插入序列的触发器。这样,每次我试图插入一个雇员(及其地址),Hibernate都会给我两个序列号(一个是父序列号,另一个是子序列号),这两个序列号都是正确设置的。然而,在进行提交的精确时刻,Oracle又给了我两个序列号,这次设置错误,我的意思是,外键与父级的主键不匹配。

但是由于我需要触发器,我必须再做一步:我必须修改这些触发器,以便它们检查:new是否正确。ID值是否为NULL。如果是,则意味着触发器是从Hibernate外部(即另一个应用程序)触发的,因此我从序列中获取nextval,否则我保留来自Hibernate的值。

 类似资料:
  • 问题内容: 我正在使用Hibernate 4.0 Final和ojdbc6开发我的Web应用程序。一切正常,除非我尝试插入新的父/子关系。首先,这些是实体: 让我们看看这两种情况: 一名员工已经存在,我尝试向其添加新地址->正常工作。 员工不存在,我尝试创建一个新员工。两种不同的情况: a)我只插入一名雇员(无地址)->可以正常工作。 b)我插入并添加了employee及其地址-> 失败 。我必须

  • 照明\database\queryexception SQLSTATE[23000]:完整性约束违反:19 NOT NULL约束失败:users.password(SQL:插入“users”(“name”、“email”、“username”、“updated_at”、“created_at”)值(MADHUP KUMAR,Chandrashivam99@gmail.com,Vansh123,20

  • 问题内容: 我正在尝试使用ALTER IGNORE TABLE + UNIQUE KEY从MySQL表中删除重复项。MySQL文档说: IGNORE是标准SQL的MySQL扩展。如果新表中的唯一键上有重复项,或者在启用严格模式时出现警告,则它控制ALTER TABLE的工作方式。如果未指定IGNORE,则在发生重复键错误时,副本将中止并回滚。如果指定了IGNORE,则只有第一行用于唯一键重复的行。

  • SQL数据库代码: 大家好!我做了一系列的桌子,我想我做的每件事都是正确的。除了位置表之外,我在所有表上输入了输入值,没有任何问题。 这就是给我的错误。 第1行错误:ORA-02291:违反完整性约束(ASSIGNMENT.FK_TENANT)-未找到父密钥。 任何帮助和提示将不胜感激。谢谢! 固定的

  • 所以这里是我的数据库: 插入表格: 批次表不断出现的错误是:ORA-02290:违反了检查约束(EJAY.batches\u DATE\u CHK) 学生表出现的错误是:ORA-02291:违反完整性约束-未找到父键 我感到困惑的是,它只显示在表格中的一些行。教职员工和课程都很好,只有这两个。如果答案很明显,我道歉,我是初学者。请帮帮忙

  • 我被要求解决的最初问题是: 创建两个表:Employee:empID(PK)、empFname、empLname、deptID(FK)和Department:deptID(PK)、deptName、chairID。chairID是Employee表中的empID。在Department表中至少插入3行,在Employee表中至少插入6行。更新chairID时创建触发器,强制执行以下业务规则:一名员