2011-03-25 77 views
1

我一直在努力解決這個問題一段時間了,似乎無法在任何地方找到解決方案。也許我誤解了一些東西,但是如果有人能爲我解決問題,我會非常感激。JPA 2 - OneToOne交叉引用

我想創建一個OneToOne之間的User.class和FacebookProfile.class之間的雙向關係。 這就是我希望能夠從FacebookProfile實體查找對應的用戶實體,反之亦然:

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

User.class

​​

FacebookProfile.class

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

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

} 

的Fac ebookProfile用戶實例在控制器中創建,然後通過服務層發送到保留對象的DAO類。

我首先創建並堅持一個新的用戶對象。

我然後創建一個新的FacebookProfile,並把新創建的用戶在它(SETUSER)。然後我堅持FacebookProfile對象。

用戶ID是現在存儲在FacebookProfile數據庫表,但沒有從用戶到FacebookProfile參考,因此下面的代碼返回一個的NullPointerException

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

下面是代碼從控制器如果有任何不明白:

 
     //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參考是在用戶對象設置,但從來沒有嘗試的一個堅持,因爲用戶對象是堅持後,這是設置。我正在使用JPA2EclipseLink

如果有人有解決這個問題,將不勝感激。

回答

2

雙向關係不由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); 
     } 
    } 
+0

太棒了!所以我一直在爲此而苦苦掙扎......手動維護?你能詳細說明一下嗎? – avonhalo 2011-03-25 20:05:44