1

我正在尝试使用带有注释的 Hibernate3 对单向 OneToMany 关系进行建模。场景是一个用户很多文章,一篇文章​​很多用户。在工作流程中,用户可以阅读其中一篇文章,在这种情况下,我想将其移动到“已读”文章的持久列表中。就 Java 模型而言,这就是一对多关系发生的地方。用户拥有属于该个人用户的“已读”文章列表。

问题是表可以有很多用户和很多文章,所以主键应该是 user_id 和 article_id 的组合。但是,在我当前的设置中,article_id 被设置为主键。这造成了一个错误,我可以在第一次准备好时将“已读”文章插入表中,但一旦第二个用户尝试阅读该文章,它就会引发重复键异常。

这是我的Java设置:

@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, orphanRemoval=true)
@JoinTable(name = "educational_article_read", joinColumns = {
    @JoinColumn(name = "user_id")}, inverseJoinColumns = {
    @JoinColumn(name = "article_id")})
@Cascade({CascadeType.ALL})
private List<EducationalArticleModel> articles_read = new ArrayList<EducationalArticleModel>();

这是生成的表模式:

mysql> describe educational_article_read;
+------------+---------+------+-----+---------+-------+
| Field      | Type    | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| user_id    | int(11) | NO   | MUL | NULL    |       |
| article_id | int(11) | NO   | PRI | NULL    |       |
+------------+---------+------+-----+---------+-------+
2 rows in set (0.05 sec)

错误堆栈跟踪:

org.springframework.dao.DataIntegrityViolationException: Duplicate entry '55' for key 'article_id'; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Duplicate entry '55' for key 'article_id'
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:138)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:594)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:476)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:387)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at com.bosch.dao.UserDAO$$EnhancerByCGLIB$$f17df281.update(<generated>)
4

0 回答 0