users@glassfish.java.net

Re: Problems with EntityManager.remove() on Glassfish (Build 48)

From: Pavel Buzek <Pavel.Buzek_at_Sun.COM>
Date: Thu, 25 May 2006 16:07:02 -0400

try this:

     // Merge the detached entity back in
-- em.merge(subscription);
++ subscription = em.merge(subscription);

-pavel

Craig McClanahan wrote:

> I'm experimenting with the new JPA APIs by writing some simple
> CRUD-based examples. Add, update, and display all work great ... but
> I'm running into an exception (documented below) when trying to remove a
> detail row. I am using Glassfish Build 48, and building the test code
> with NB 5.5 beta.
>
> I've got two entity classes that, among other things, have a
> bidirectional one-to-many relationship with each other:
>
> @Entity
> public class User implements Serializable {
> ....
> @OneToMany(mappedBy="user")
> private List<Subscription> subscriptions;
> ...
> public List<Subscription> getSubscriptions() { return
> this.subscriptions; }
> public void setSubscriptions(List<Subscription> subscriptions) {
> this.subscriptions = subscriptions;
> }
> ...
> }
>
>
> @Entity
> public class Subscription implements Serializable {
> ...
> @ManyToOne
> private User user;
> ...
> public User getUser() { return this.user; }
> public void setUser(User user) { this.user = user; }
> ...
> }
>
> Note that the above classes correctly implement hashCode() and equals()
> as well ... without that the comparisons performed would be failing.
>
> According to the JPA specification, it is the application's
> responsibility to maintain the properties that implement the
> relationship, so I've added a convenience method to the User class like
> this:
>
> public void removeSubscription(Subscription subscription) {
> if ((subscriptoin == null) || (subscriptions == null)) {
> return;
> }
> if (subscriptions.contains(subscription)) {
> subscriptions.remove(subscription);
> subscription.setUser(null);
> }
> }
>
> Now, my business logic looks like this:
>
> @PersistenceContext
> EntityManager em; // Injected for me
>
> @Resource
> UserTransaction utx; // Injected for me
>
> Subscription subscription = ...; // A detached copy of a Subscription
> entity
> // Start a transaction
> utx.begin();
> // Merge the detached entity back in
> em.merge(subscription);
> // Attempt to remove the subscription
> subscription.getUser().removeSubscription(subscription);
> // Remove the subscription from the database too
> em.remove(subscription);
> // Complete the transaction
> utx.commit();
>
> However, I get an exception from TopLink Essentials that looks like this:
>
> java.lang.NullPointerException
> at
> oracle.toplink.essentials.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:217)
>
> at
> oracle.toplink.essentials.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:82)
>
> at
> oracle.toplink.essentials.indirection.IndirectList.buildDelegate(IndirectList.java:193)
>
> at
> oracle.toplink.essentials.indirection.IndirectList.getDelegate(IndirectList.java:315)
>
> at
> oracle.toplink.essentials.indirection.IndirectList.contains(IndirectList.java:249)
>
> at myjpaexample.User.removeSubscription(User.java:99)
>
>
> where line 99 in User is the line inside removeSubscription() that calls
> "subscriptions.contains()". Various attempts to remove the subscription
> from the list by other means all seem to end up with an NPE at the same
> place.
>
> Any ideas?
>
> Craig McClanahan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>