Reputation: 8183
I'm trying to add an object to a collection in my client view and to save it on server with hibernate/jpa mechanism.
Here is the problem: Take a Group object which can contains Account objects.
On my client view (gwt), I create a new group (so the id is null) and I add to this group some accounts (where ids exist). BUT these accounts are initialized in client with their id and pseudo only via a suggest box (because I don't want to load password and other stuff in my client view)
When my group returns to server, I try to save it with my dao and I've got this error: not-null property references a null or transient value
Here is my association in Group object:
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public Set<Account> getAccounts()
{
return accounts;
}
so the persist must be done automatically. But I think the problem is that I use partial account objects with existing id.
My question is: How can I add a simple association (just add a record in the manyToMany table) without loading all objects that I want to add (because I don't need it, I just want to add an association between two id)
EDIT: more information by example: I've got a group which properties are id:"G1" name:"group1"
I've got the account which properties are id:"A1" pseudo:"jerome" password:"pass1" status:"enabled" birthday:"xxxx" ...
From my client interface (done with gwt) I load the group1 object From an autcompletion I load Account objects but only with field id and pseudo (I don't want to load all the object). I add the Account object "Jerome" with id "A1" to my group.
I send my group to server to save it. In server I use a transactional method which save the group by calling: groupDAO.update(myGroup1)
As my Account object in this Group object is partially loaded, it causes an error.
So, How can I add the association between my group and account without loading the entire object Account ? I don't want this sort of code:
List newList = new ArrayList();
for (Account acc : myGroup1.getAccounts())
{
Account accLoaded = accountDAO.findById(acc.getId());
newList.add(accLoaded);
}
myGroup1.setAccounts(newList);
groupDAO.save(myGroup1);
thanks
Upvotes: 3
Views: 3312
Reputation: 33783
Your goal:
I just want to add an association between two id without loading the entire object Account
You said:
I think the problem is that i use partial account objects with existing id
You are right. Suppose the following
public class Account {
private Integer id;
private Integer accountNumber;
@Id
public Integer getId() {
return this.id;
}
@Column(nullable=false)
public Integer getAccountNumber() {
return this.accountNumber;
}
}
So when you call
Group group = new Group();
// Notice as shown bellow accountNumber is null
Account account = new Account();
account.setId(1);
group.addAccount(account);
entityManager.persist(group);
So because of CascadeType.PERSIST, you are saying
Save each referenced Account
But each referenced Account accountNumber property is null. It explains why you get your exception
Instead of loading a fully initialized Account You can use something like
// If you do not want to hit the database
// Because you do not need a fully initialized Account
// Just use getReference method
Account account = entityManager.getReference(Account.class, new Integer(accountId));
So it does not make sense you load each fully initialized Account without any purpose or reason.
regards,
Upvotes: 4