JPA 2 - перекрестная ссылка OneToOne - PullRequest
1 голос
/ 25 марта 2011

Я уже давно борюсь с этой проблемой и, похоже, нигде не могу найти решения. Может быть, я что-то не так понял, но был бы очень признателен, если бы кто-то мог прояснить для меня вещи.

Я пытаюсь создать двунаправленную связь OneToOne между классом User.class и FacebookProfile.class. То есть я хочу иметь возможность искать соответствующую сущность пользователя из сущности FacebookProfile, и наоборот:

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

My 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;

}

Новые FacebookProfile и Пользовательские экземпляры создаются в Контроллере, а затем отправляются через слой Service в класс DAO, в котором сохраняются объекты.

Сначала я создаю и сохраняю новый Пользователь объект.

Затем я создаю новый FacebookProfile и помещаю в него вновь созданного пользователя (setUser). Затем я сохраняю объект FacebookProfile.

Идентификатор пользователя теперь хранится в таблице базы данных 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 была установлена ​​в объекте Пользователь , но никогда не сохранялась, поскольку она была установлена ​​после того, как объект Пользователь был сохранялось. Я использую JPA2 и EclipseLink .

Если у кого-то есть решение, оно будет очень признательно.

1 Ответ

2 голосов
/ 25 марта 2011

Двунаправленные отношения не поддерживаются 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);
       }
    }   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...