【问题标题】:JPA 2 - OneToOne cross referenceJPA 2 - OneToOne 交叉引用
【发布时间】:2011-07-22 22:53:01
【问题描述】:

我已经为这个问题苦苦挣扎了一段时间,似乎无法在任何地方找到解决方案。也许我误解了一些东西,但如果有人能为我解决问题,我将不胜感激。

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

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

我的User.class

@实体 @Access(值=AccessType.FIELD) 公共类用户实现 UserDetails { @OneToOne(mappedBy="user") 私人 Facebook 个人资料 fbprofile; }

我的FacebookProfile.class

@实体 @Access(值=AccessType.FIELD) 公共类 FacebookProfile { @OneToOne(级联=CascadeType.ALL) @JoinColumn(name="用户") 私人用户用户; }

新的 FacebookProfileUser 实例在控制器中创建,然后通过服务层发送到持久化对象的 DAO 类。

我首先创建并持久化一个新的 User 对象。

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

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

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

如果不清楚,以下是来自控制器的代码:

//检查Facebook用户是否已经存在 FacebookProfile fbprofile = facebookProfileService.findFacebookProfileById(fbId); 用户新用户; //如果不存在则创建一个新的FacebookProfile 如果(fbprofile == null){ //检查是否有用户注册了facebook邮箱 newUser = userService.findUserByEmail(fbEmail); // 没有用户,也没有 FacebookProfile 存在 if(!newUser.isEnabled()){ 新用户 = 新用户(); newUser.setFirstname(fbFirstname); newUser.setLastname(fbLastname); //设置邮箱 电子邮件 mail = new Email(); mail.setAddress(fbEmail); mail.setName("Facebook"); newUser.addEmail(邮件); //设置性别 如果(fbGender.equalsIgnoreCase(“女性”)){ newUser.setGender(Gender.FEMALE); }否则如果(fbGender.equalsIgnoreCase(“男性”)){ 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); 如果(!fbHometown.equals(“”)){ newProfile.setHometown(fbHometown); newProfile.setHometownID(Long.parseLong(fbHometownID)); } if(!fbLocation.equals("")){ newProfile.setLocation(fbLocation); newProfile.setLocationID(Long.parseLong(fbLocationID)); } newProfile.setLink(fbLink); 如果(fbGender.equalsIgnoreCase(“男性”)){ newProfile.setGender(Gender.MALE); }else if (fbGender.equalsIgnoreCase("female")) { newProfile.setGender(Gender.FEMALE); } newProfile.setUser(newUser); this.facebookProfileService.createNewFacebookProfile(newProfile); //newUser.setFbprofile(newProfile); }else { //已经存在一个FacebookProfile newUser = fbprofile.getUser(); }

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

如果有人对此有解决方案,将不胜感激。

【问题讨论】:

    标签: java jpa persistence eclipselink one-to-one


    【解决方案1】:

    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);
           }
        }   
    

    【讨论】:

    • 太棒了!所以我一直在为此苦苦挣扎……手动维护?你能详细说明一下吗?
    猜你喜欢
    • 2012-04-05
    • 2022-12-17
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 2022-10-25
    • 2011-08-15
    • 2011-03-03
    • 2013-11-11
    相关资源
    最近更新 更多