java - JPA 和 hibernate - 更新/合并一对多关系

标签 java hibernate jpa

首先,这是代码

@Entity
@SequenceGenerator(name = "wordlist_seq", sequenceName = "wordlist_seq")
public class QuestionSet {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "wordlist_seq")
    private Long id;

    @Constraints.Required
    private String name;

    @Constraints.Required
    private String questionType;

    @Constraints.Required
    @ManyToOne
    @PrimaryKeyJoinColumn
    private User owner;

    public String getQuestionType() {
        return questionType;
    }

    public void setQuestionType(String questionType) {
        this.questionType = questionType;
    }

    @OneToMany(cascade = CascadeType.ALL)
    private List<Question> questions;
....

这是一些示例操作

@SecureSocial.SecuredAction
@play.db.jpa.Transactional
public static Result test(){
    QuestionSet set = questionSetDAO.findByID(QuestionSet.class, 100L);
    List<Question> questions = new ArrayList<Question>();
    OpenQuestion question = new OpenQuestion();
    question.setQuestion("a");
    question.setAnswer("b");
    questions.add(question);
    set.setQuestions(questions);
    questionSetDAO.merge(set);
    return ok();
}

现在,当我更新 QuestionSet 类的某些实例时,我从数据库中获取它,创建新的问题列表(它可能包含一些没有 id 集的新问题,它可能包含具有现有 id 的问题 - 这些问题用于更新)。

现在,当我调用实体管理器的 merge 方法时,我收到以下异常:

play.api.Application$$anon$1: Execution exception[[RollbackException: Error while committing the transaction]]
    at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.1]
    at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10.jar:2.1.1]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:144) [play_2.10.jar:2.1.1]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:140) [play_2.10.jar:2.1.1]
    at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1]
    at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1]
javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:93) ~[hibernate-entitymanager-3.6.9.Final.jar:3.6.9.Final]
    at play.db.jpa.JPA.withTransaction(JPA.java:107) ~[play-java-jpa_2.10.jar:2.1.1]
    at play.db.jpa.TransactionalAction.call(TransactionalAction.java:14) ~[play-java-jpa_2.10.jar:2.1.1]
    at securesocial.core.java.SecureSocial$Secured.call(SecureSocial.java:218) ~[securesocial_2.10-master-SNAPSHOT.jar:master-SNAPSHOT]
    at play.core.j.JavaAction$$anon$2.apply(JavaAction.scala:74) ~[play_2.10.jar:2.1.1]
    at play.core.j.JavaAction$$anon$2.apply(JavaAction.scala:73) ~[play_2.10.jar:2.1.1]
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387) ~[hibernate-entitymanager-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315) ~[hibernate-entitymanager-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81) ~[hibernate-entitymanager-3.6.9.Final.jar:3.6.9.Final]
    at play.db.jpa.JPA.withTransaction(JPA.java:107) ~[play-java-jpa_2.10.jar:2.1.1]
    at play.db.jpa.TransactionalAction.call(TransactionalAction.java:14) ~[play-java-jpa_2.10.jar:2.1.1]
    at securesocial.core.java.SecureSocial$Secured.call(SecureSocial.java:218) ~[securesocial_2.10-master-SNAPSHOT.jar:master-SNAPSHOT]
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
Caused by: org.h2.jdbc.JdbcBatchUpdateException: Referential integrity constraint violation: "FK415AFE694BC8D057: PUBLIC.QUESTIONSET_QUESTION FOREIGN KEY(QUESTIONS_ID) REFERENCES PUBLIC.QUESTION(ID) (200)"; SQL statement:
insert into QuestionSet_Question (QuestionSet_id, questions_id) values (?, ?) [23506-168]
    at org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1121) ~[h2.jar:1.3.168]
    at com.jolbox.bonecp.StatementHandle.executeBatch(StatementHandle.java:469) ~[bonecp.jar:0.7.1.RELEASE]
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]

在我的简单示例操作中,问题集开头不包含任何问题,因此列表为空。

似乎hibernate首先尝试将问题插入由OneToMany注释创建的连接表中,并且我收到错误,因为引用的实体尚未在数据库中,但我认为@OneToMany(cascade = CascadeType.ALL)会处理这种事情?

最佳答案

我正在回答我自己的问题,因为我发现我有一些以前的注释留下的内容,所以我当前的模型不应该存在这个约束。我清除了数据库,现在一切正常。

关于java - JPA 和 hibernate - 更新/合并一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16262705/

相关文章:

java - 无法测试 JPA + Spring

java - 如何检查 Hashmap 值中的子字符串

java - 使用 System.exit(0) 强制退出 Android 应用程序不起作用

mysql - 能够生成 UUID 但无法将其插入数据库

java - 在 EJB Helper 类中查找实体管理器

java - 锁定相互交易执行

java - Java 和 C++ 中的类似程序不同的输出

java - 使用 Jenkins 构建和 maven 项目进行 Sonar 分析时,无法通过 ClassLoader 警告访问类 'XXX/XXX/XXX '

hibernate - 如果数据在进入数据库之前需要修剪,您将其放入哪一层

Spring、spring Batch、hibernate 和 JUnit 以及多个集成测试的初始化