简体   繁体   English

OneToOne + No Foreginkey + Unidirectional + Datamissing => EntityNotFoundException

[英]OneToOne + No Foreginkey + Unidirectional + Datamissing => EntityNotFoundException

From a legacy system, we have 1 table (Entity) and 1 view (UserDetail) with no constraints but with relations. 在遗留系统中,我们有1个表(实体)和1个视图(UserDetail),没有约束但有关系。

Entity
| Id | Desc | Created_By |...

UserDetail
| UserId | F_Name | L_Name |...

CreatedBy has the userid of the user who created that entity. CreatedBy具有创建该实体的用户的用户标识。 We have a unidirectional mapping in Entity.java like below. 我们在Entity.java中有一个单向映射,如下所示。

@OneToOne
@JoinColumn(name = "CREATED_BY", referencedColumnName = "USER_ID")
private UserDetail createdBy;

Problem 问题

But since its a legacy system, we don't have control on that and an user is hard deleted. 但由于它是一个遗留系统,我们无法控制它并且用户被硬删除。

When the entityReposity.findAll is called, following error is thrown 调用entityReposity.findAll时,抛出以下错误

org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com...UserDetail with id 92237; nested exception is javax.persistence.EntityNotFoundException: Unable to find com...UserDetail with id 92237

Question

How to make the JPA consider this association is optional or is there any way in JPA to make it ignore (like @NotFound in Hibernate)? 如何让JPA认为这种关联是可选的,或者在JPA中有什么方法可以忽略它(比如Hibernate中的@NotFound)?

Tried 试着

  1. @NotFound works, but we need to hack @OneToOne as @ManyToOne. @NotFound有效,但我们需要将@OneToOne破解为@ManyToOne。 Also we want an implementation independent solution. 我们还想要一个独立于实现的解决方 Noticed this bug too, https://hibernate.atlassian.net/browse/ANN-725 注意到这个错误, https://hibernate.atlassian.net/browse/ANN-725

  2. optional=true - If this would have worked as per the syntactical meaning on how it should behave, I wouldn't have written this. optional = true - 如果这可以按照它应该如何表现的语法含义工作,我就不会写这个。

  3. Also tried the postLoad() in UserDetails.java. 还尝试了UserDetails.java中的postLoad()。

  4. @PostLoad solution We have aop exceptionhandler and exception is caught there before @PostLoad in Entity class gets called. @PostLoad解决方案我们有一个异常的异常处理程序,并且在调用Entity类中的@PostLoad之前就会捕获异常。

In Entity.java 在Entity.java中

    @PostLoad
    public void postLoad(){
        try {
            System.out.println(this.getCreatedBy()); //Before control comes here, it goes to aop exception handler
        }
        catch (EntityNotFoundException e){
            setCreatedBy(null);   
        }
    }

Any help would be appreciated. 任何帮助,将不胜感激。

As crazy as it sounds, you need to make the @OneToOne association optional = false . 听起来很疯狂,你需要让@OneToOne关联optional = false See this question and answer for an explanation. 请参阅此问题和答案以获得解释。

So the code for the association would be: 所以关联的代码是:

@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "CREATED_BY", referencedColumnName = "USER_ID")
private UserDetail createdBy;

Of course the trouble is that if you try to access the associated createdBy association, then Hibernate will try to lazy-load the associated Entity and you will get the same exception. 当然麻烦的是,如果您尝试访问关联的createdBy关联,那么Hibernate将尝试延迟加载关联的实体,您将获得相同的异常。

The @NotFound is really your best bet. @NotFound真的是你最好的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM