0

I have 2 entities User and UserSettings. I am trying to build a flow to modify UserSettings row in the DB. this is my User and UserSetting object-

@Entity
@Table(name = "user")
public class User implements Serializable{


    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "id")
    private int id;
    private String name;

    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    private DateTime createdat = new DateTime();

    @OneToMany( fetch=FetchType.EAGER)
    @JoinColumn(referencedColumnName="id", name = "userID")  
    @BatchSize(size = 50)
    @MapKey(name="name")
    @Cascade({CascadeType.ALL})
    private Map<String,UserSetting> userSetting;


    ...

}


@Entity
@IdClass(UserSetting.UserSettingId.class)
@Table(name = "usersettings")
public class UserSetting implements Serializable{


    @Id
    private String name;

    private String value;

    @Column(name="UserID",insertable = false,updatable = false) //
    private Integer userId;

    @Id
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="userID")
    private User user;

    ...
}

before modifying the UserSetting I am trying to fetch the object, modifying its value, and then using the save method.

this is the method for saving the modified data -

public void saveUserSettings(int userId, String name, String value) {

    UserSetting userSetting = new UserSetting();
    userSetting.setUserId(userId);
    userSetting.setName(name);
    userSetting.setValue(value);

    User user = usersRepository.findOne(userId);
    userSetting.setUser(user);

    userSettingRepository.save(userSetting);
}

the save always fails, because the user that returns from usersRepository.findOne(userId) is a lazy object and not the actual one.

Why does this happen? How can I make the find one return the actual object?

thanks ahead

Yair

yairbr
  • 49
  • 1
  • 3

3 Answers3

0

Use EntityManager#getReference

@Autowired
    EntityManager em;

    public void saveUserSettings(int userId, String name, String value) {

        UserSetting userSetting = new UserSetting();
        userSetting.setUserId(userId);
        userSetting.setName(name);
        userSetting.setValue(value);

        User user = em.getReference(userId,User.class); // no actual fetch
        userSetting.setUser(user);

        userSettingRepository.save(userSetting);
    }
Antoniossss
  • 24,977
  • 3
  • 43
  • 86
0

Try this:

UserSetting userSettingDb = usersRepository.findOne(userId); User user = userSettingDb.getUser(); userSetting.setUser(user);`

userSettingRepository.save(userSetting);`
kj007
  • 5,072
  • 3
  • 22
  • 42
  • tried it. not working since userSettingDb.getUser(); returns null – yairbr Dec 11 '17 at 08:07
  • Of course it will return Null as you are tying to find user settings by user id, create your custom method in user setting repository findOneByUSer_UserId(int UserId) and call it to get user setting the get user. – kj007 Dec 11 '17 at 08:51
  • who said this is how I retrieved the userSetting object? I user a method to retrieve it by name and userId (which are its primary key). still returns null. – yairbr Dec 11 '17 at 09:05
  • ok, i thought you were updating UserSettings and trying to get user from user settings then seems nothing wrong with your logic, do you have user for corresponding userId?? if yes then can you post error you are getting as its not related to lazy loading as you are loading User from user entity. – kj007 Dec 11 '17 at 09:13
0

I fixed the problem by forcing the lazy object returning the implementation (unproxying).

got the answer from - https://stackoverflow.com/a/2216603/4797399

yairbr
  • 49
  • 1
  • 3