【问题标题】:@ManyToOne of the same type as parent where child doesn't exist in DB@ManyToOne 与父级相同类型,其中子级在 DB 中不存在
【发布时间】:2014-04-02 19:13:04
【问题描述】:

我使用 Spring Roo 对 MySQL 数据库进行了逆向工程,这是一个我只有读取权限的数据库。

其中一个名为 Transaction 的实体有一个名为 originalTransaction 的字段,在 DB 中设置为可以为 null,但默认值为 0。

@RooJavaBean
@RooToString
@SuppressWarnings("serial")
@RooDbManaged(automaticallyDelete = true)
@RooJpaActiveRecord(versionField = "", table = "TRANSACTIONS")
public class Transaction implements Serializable {

    ....

    @Fetch(value = FetchMode.SELECT)
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "ORIG_TRANS_ID")
    private Transaction originalTransaction;

    ....

}

我添加了 FetchMode.Select 和 FetchType.Lazy 作为其他问题的解决方法。

现在,当我插入一个事务并将 originalTransaction 保留为空时,数据库会将其更改为 0。

当我执行 entity().find(12345678) 时,出现以下错误:

Unable to find Transaction with id 0

javax.persistence.EntityNotFoundException: Unable to find Transaction with id 0
        at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:157)
        at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:261)
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:175)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)    

很明显(最初并不那么明显),它试图找到 originalTransaction 并且由于 DB 将 null 更改为 0,它试图找到不存在的 id=0 的 Transaction - 这会导致实体。即使事务在数据库中,find(12345678) 也会返回 null。

如果数据库中的 originalTransaction 的 id 不存在,是否有任何解决方法可以阻止 Hibernate / JPA 放弃搜索并返回 null?如果它不存在,我最好强制它为空。

【问题讨论】:

  • @SuppressWarnings 总是让我内心抽搐。 :) 不过,对你写得很好的问题 +1。
  • @SuppressWarnings 实际上应该消失,该类缺少“public static final long serialVersionUID = _____L;”感谢您指出:-)

标签: java mysql hibernate jpa spring-roo


【解决方案1】:

如果你使用 Hibernate 你可以试试

@NotFound(action = NotFoundAction.IGNORE)

否则你必须清理你的数据库(0 不是null)。如果没有父级,ORIG_TRANS_ID 应该是null

【讨论】:

  • @NotFound 是一种绕过问题的方法,无论如何它会导致额外的 ID 为 0 的查询。最好的解决方案是在该外键上保留一个空值(使用 0 作为 FK 确实是对数据库设计的坏方法)。也许自定义休眠类型也有帮助,但我不确定,无论如何我更喜欢上面建议的方法。
  • @agori,如果我有权更改数据库,我会立即将其删除,我认为主要问题是停机时间,数据库在过去 10 多年中一直存在,可能有 5该表中的 -1000 万条记录并执行更改表将导致表锁定,更不用说破坏依赖于该 0 的遗留代码。
  • @drkunibar,(at)NotFound,看来可以解决问题了,谢谢指点!
猜你喜欢
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-29
  • 1970-01-01
  • 2021-07-20
相关资源
最近更新 更多