Heruan Heruan - 2 months ago 29
Java Question

Jackson JPA persisting foreign key composite-id fails

I have a JPA entity with a foreign key being part of a composite-id:

@Entity
@IdClass(CustomerId.class)
public class Customer {

@Id
public String id;

@Id
@ManyToOne
public Company company;

}

public class CustomerId {

public String id;

public String company;

}

@Entity
public class Company {

@Id
public String id;

public String name;

}


and it works. Problem is when I receive a JSON object to be persisted and Jackson unserializes it to a POJO:

{
"id": "Cust0001",
"company": {
"id": "Comp1"
}
}


and this the JAX-RS resource:

@Path("/customers")
public class CustomerResource {

@PersistenceContext
EntityManager em;

@POST
@Consumes(MediaType.APPLICATION_JSON)
public void post(Customer customer) {
em.persist(customer);
}

}


this fails, since JPA (I use Hibernate) tries to cascade
persist
to an unmanaged instance of
Company
with
id
"Comp1", thus throwing a
EntityExistsException
.

The only way I've found to make this work is:

customer.company = em.merge(customer.company);
em.persist(customer);


but I'm looking for a generalized solution since I have dozens of entities like
Customer
and their JAX-RS resources extend an abstract resource where I don't know what to merge/set before persist the entity.

UPDATE

Same problem when try to merge two unserialized objects with a reference to the same entity, e.g.

{
"id": "Cust0001",
"company": {
"id": "Comp1"
},
relatedCustomer: {
"id": "Cust9999",
"company": {
"id": "Comp1"
}
}
}


merging this also throws an
EntityExistsException
regarding
Company#Comp1
.

Answer

Resolved using @JsonIdentityInfo on entity classes, which make Jackson de/serialize objects with no redundancy using identifiers associated with the same instance of each entity.

Comments