java - JPA 2 - 一对一交叉引用

标签 java jpa persistence eclipselink one-to-one

我已经被这个问题困扰了一段时间,似乎无法在任何地方找到解决方案。也许我误解了一些东西,但如果有人能为我澄清事情,我将非常感激。

我正在尝试在 User.class 和 FacebookProfile.class 之间创建 OneToOne 双向关系。 也就是说,我希望能够从 FacebookProfile 实体查找相应的 User 实体,反之亦然:

userInstance.getFbprofile();
fbprofileInstance.getUser();

我的User.class:

@Entity
@Access(value=AccessType.FIELD)
public class User implements UserDetails {

    @OneToOne(mappedBy="user")
    private FacebookProfile fbprofile;

}

我的FacebookProfile.class:

@Entity
@Access(value=AccessType.FIELD)
public class FacebookProfile {

    @OneToOne (cascade=CascadeType.ALL)
    @JoinColumn(name="USER")
    private User user;

}

新的 FacebookProfileUser 实例在 Controller 中创建,然后通过服务层发送到保存对象的 DAO 类。

我首先创建并保留一个新的User对象。

然后,我创建一个新的 FacebookProfile 并将新创建的 User 放入其中 (setUser)。然后我保留 FacebookProfile 对象。

用户 ID 现在存储在 FacebookProfile 数据库表中,但用户没有对 FacebookProfile 的引用,因此以下代码返回 NullPointerException:

User tempUser = userService.findUserById(newUser.getId());
System.out.println("ID "+tempUser.getFbprofile().getId());

如果有不清楚的地方,下面是 Controller 的代码:

        //Check if the Facebook user already exist
        FacebookProfile fbprofile = facebookProfileService.findFacebookProfileById(fbId);


        User newUser;

        //Create a new FacebookProfile if it doesn't exist
        if(fbprofile == null){

            //Check if there is a user registered with the facebook email
            newUser = userService.findUserByEmail(fbEmail);

            // No User and No FacebookProfile exists
            if(!newUser.isEnabled()){

                newUser = new User();

                newUser.setFirstname(fbFirstname);
                newUser.setLastname(fbLastname);

                //Set email
                Email mail = new Email();
                mail.setAddress(fbEmail);
                mail.setName("Facebook");
                newUser.addEmail(mail);

                //Set gender
                if(fbGender.equalsIgnoreCase("female")){
                    newUser.setGender(Gender.FEMALE);
                }else if(fbGender.equalsIgnoreCase("male")) {
                    newUser.setGender(Gender.MALE);
                }

                userService.createUser(newUser);

            }

            FacebookProfile newProfile = new FacebookProfile();
            newProfile.setId(Long.parseLong(fbId));
            newProfile.setUsername(fbUsername);
            newProfile.setFirstname(fbFirstname);
            newProfile.setLastname(fbLastname);
            newProfile.setName(fbName);
            newProfile.setEmail(fbEmail);

            if(!fbHometown.equals("")){
                newProfile.setHometown(fbHometown);
                newProfile.setHometownID(Long.parseLong(fbHometownID));
            }

            if(!fbLocation.equals("")){
                newProfile.setLocation(fbLocation);
                newProfile.setLocationID(Long.parseLong(fbLocationID));
            }

            newProfile.setLink(fbLink);

            if(fbGender.equalsIgnoreCase("male")){
                newProfile.setGender(Gender.MALE);
            }else if (fbGender.equalsIgnoreCase("female")) {
                newProfile.setGender(Gender.FEMALE);
            }


            newProfile.setUser(newUser);
            this.facebookProfileService.createNewFacebookProfile(newProfile);

            //newUser.setFbprofile(newProfile);


        }else { //There already exists a FacebookProfile

            newUser = fbprofile.getUser();
        }

我觉得我已经尝试了所有可能的解决方案,但还没有成功。 我怀疑在我之前的一次尝试中,fbprofile引用是在User对象中设置的,但从未持久化,因为它是在User之后设置的> 对象被持久化。我正在使用 JPA2EclipseLink

如果有人能解决这个问题,我们将不胜感激。

最佳答案

JPA 不维护双向关系。 JPA 设计者曾认为维护双向关系会导致死锁、不一致... Toplink 在 JPA 之前就支持双向关系.. 我使用 Toplink 已经很多年了,我确实遇到过一些与双向关系相关的不一致问题。 .你应该手动维护双向关系..如;

newProfile.setUser(newUser);
newUser.setFbProfile(newProfile);

编辑:

好吧,您希望我详细说明我的答案。您应该更改保留 FbProfile 实体的代码,例如;

    newProfile.setUser(newUser);
    newUser.setFbprofile(newProfile);
    this.facebookProfileService.createNewFacebookProfile(newProfile);

作为替代方案,您还可以更改 FbProfile setUser 方法;

    public void setUser(User aUser) {
       if (this.user==aUser)
          return;
       if (this.user != null) {
          this.user.setFbProfile(null);
       }
       this.user = aUser;
       if (this.user!=null) {
           this.user.setFbprofile(this);
       }
    }   

关于java - JPA 2 - 一对一交叉引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5433485/

相关文章:

java - SAX解析器中的Character()方法

hibernate - Spring 中与 Hibernate 的 SQL 连接异常

java - 使用 jpa 实体管理器从表中选择过滤记录

Java JPA/hibernate : How to avoid multiple instances of an entity in a session?

hibernate - 如何测试具有不可空集合的持久实体

java - Netbeans Spring Boot Initializr 项目 : Unable to see jsp content in web browser

java - 将 period 与 periodType.forFields 一起使用时出现异常

spring-boot - 如何使用 Spring Data JPA(Hibernate) 跨映射表过滤关联实体?

java - 重新附加实体以延迟加载集合(JPA/Hibernate)

java - 如何通过 JOptionPane 格式化十进制数字的输出