Bax Bax - 2 months ago 10
Java Question

Issue in persisting changes to an entity involving an unowned relationship

I'm developing a GWT + AppEngine application which works just fine in the development environment. But when I deployed it to GAE, a strange issue occurred.

The code below (simplified of course) shows the JPA entities involved. The Product entity owns a intermediate entity called ProductSubscription. This in turn contains a reference to the unowned entity Subscription, which contains an owned list of Discount entities. The reason why Subscription is unowned is that I need multiple Products to be associated with the same Subscription.

@Entity
public class Product
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

// Product subscription details
@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.EAGER)
private ProductSubscription productSubscription;
}


@Entity
public class ProductSubscription
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

@Basic(fetch=FetchType.EAGER)
@Unowned
private Subscription subscription;

@OneToOne(optional=false, mappedBy="productSubscription", targetEntity=Product.class, fetch=FetchType.LAZY)
private Product product;
}


@Entity
public class Subscription
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;

@OneToMany(cascade=CascadeType.ALL, mappedBy="subscription", orphanRemoval=true, fetch=FetchType.EAGER)
private List<Discount> discounts;
}


@Entity
public class Discount
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

@ManyToOne(optional=false, targetEntity=Subscription.class, fetch=FetchType.LAZY)
private Subscription subscription;
}


In my workflow I create the Subscription objects and their Discounts. Then in a separate transaction I associate the Subscription to a Product through LicenseSubscription.

The issue occurs when I make changes to Product and persist it: the Discounts disappear from Subscription! Meaning that the entities are automatically deleted from the datastore.
Anybody can explain what I'm doing wrong? My assumption was that as I'm using an unowned relationship, no changes to Product or ProductSubscription object should have an impact on Subscription (and in fact everything works fine in dev).

Any help will be appreciated, as I'm now stuck. Thanks.

Bax Bax
Answer

Turned out that while updating the Product, in order to evaluate the Discount to be applied, I was sorting the discounts collection like this:

Collections.sort(discounts, Discount.DESCENDING_COMPARATOR);

Now I changed this to a more appropriate @OrderBy statement on the list declaration in the Subscription entity and everything works fine.

I'm still curious to understand why that sorting caused all discounts to be removed from the subscription, so any comment on this will be appreciated. Thanks.