Specifying One-to-one relationship foreign key in JPA - jpa

I am implementing REST API using Spring and JPA. Consider for example the following scenario where there are Project and Department entities where a Project belongs to a single Department. I would normally have a Department object referenced in Project Pojo, with a #OneToOne annotation.
When creating a Project through REST API (where a Department is already created), I am currently getting departmentID as an attribute from the user, loading Department object using the ID, associating it to the Project and then saving the Project instance using JPA. Is there a way to avoid this and directly save the Project by specifying department ID directly?

Create two entity classes like
class Department{
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL,
mappedBy = "department")
Project project;
}
class Project{
}

Related

Multiple representations of the same entity are being merged, Detached

I have been getting an error while trying to update a list of entities containing persisted entity and detached entity both (newly created entity) into my db using jpa2.0.
My entity contains internal entities which are giving an error (mentioned in the title) when merging the data:
Class superclass{
private A a;
private string name;
//getter setters here...
}
Class A{
private long id;
#onetoone(cascade=CascadeType.All, fetch=FetchType.Eager)
private B b;
#onetoone(cascade=CascadeType.All, fetch=FetchType.Eager)
private C c;
//getter setters here...
}
Class Dao{
daoInsert(superclass x){
em.merge(x);
}
}
I want any entity sent for persisting to be merged into the db.
Hibernate does provide solution for this by adding the following to the persistence.xml
Is there something I can do in jpa same as hibernate.
Please do not suggest to find the entity using em.find() and then update manually because I need both entities the persisted entity and the newly created entity too.
Also I'm using spring form to persist the entire patent entity into db.
I am sorry if I'm not clear enough, this is my first question and I'm really a beginner.
Any help will be most appreciated.
Found an answer to the question myself today.You just need to
remove CascadeType.MERGE from the entity that is not allowing you to persist the detached entity.
if you're using CascadeType.ALL then mention all cascade type other than CascadeType.MERGE.
Now removing CascadeType.MERGE from cascade is one solution but not a best solution because after removing MERGE from Cascade you won't be able to update the mapped object ever.
If you want to merge the Detached entity with Hibernate then clear the entity manager before you merge the entity
entityManager.clear();
//perform modification on object
entityManager.merge(object);
To solve this problem make sure to specify that the identifiers of your objects are automatically generated by adding #GeneratedValue(strategy = GenerationType.IDENTITY) on the identifaint such as id.
In this way when the merge will be carried out, the identifier of the elements to merge will be automatically incremented, compared to the other object already recorded in the database to avoid primary key conflicts

JPA #OneToOne with an Entity that is not exported from it's OSGi Bundle

I am trying to set up a simple foreign key relation ship using JPA in a rather complex OSGi environment.
The two entities I want to use are structured in bundles like so:
masterbundle
|->org.masterpackage.persistence
|-> MasterEntityDto.java
slavebundle
|->org.slavepackage.persistence
|-> SlaveEntity.java
SlaveEntity want to refer to the MasterEntityDtolike so
#Entity(name = "SlaveEntity")
public class SlaveEntity {
#Id
#Column(name = "slaveID")
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#OneToOne
#JoinColumn(name = "masterEntity_id")
private MasterEntity masterEntity;
// snip..
}
Now, this fails because masterbundle is not exporting the MasterEntityDto (or its package), I think. We are using the Service Aspect of OSGi, masterBundle is provide-interface-ing a service that is using the Dto instead of the Dto.
The exception I see when the bundle starts says, among other things org.osgi.framework.BundleException: Unresolved constraint in bundle slavebundle [121]: Unable to resolve 121.8: missing requirement [121.8] osgi.wiring.package;
Question: How do I create a #OneToOne relation from SlaveEntity to MasterEntityDto? Is this not possible in when using the OSGi service platform and I only expose services and not whole bundles / packages?
Edit1
As per request: MasterEntityDto has nothing fancy.
#Entity(name = "MasterEntityDto")
public class MasterEntityDto {
#Id
#Column(name = "id", length = 128)
private String masterId;
// snip
}
I would want JPA to make a SlaveEntity - table with columns SlaveId (which is this tables PK) and masterEntity_id which would act as foreign key, pointing to table MasterEntityDto's id column.
The packages containing domain classes (such as MasterEntityDto) do need to be exported, so that the JPA bundle can have visibility to instantiate them.
Because of this it is very important to keep such packages separated from other packages containing implementation/logic code, which should be private.

JPA Simple ForeignKey relationship

Is it possible to create a basic FK relationship in JPA without involving the full entity target object?
As an example, imagine I have an entity:
#Entity(name = "Mechanic")
public class Mechanic {
#Id
private Long id;
//...
and a Car that I want to reference a Mechanic.id:
#Entity(name = "Car")
public class Car {
//...
#NotNull
private Long mechanic_id;
From an Object perspective, this would be a unidirectional, one to one relationship with the Car requiring a Mechanic.id and the Mechanic not needing any back reference to Car.
All I want out of this is to store the Mechanic.id ONLY. For the purposes of this question it is not useful to have a #OneToOne (or #OneToMany etc) relationship with the entity reference, I'm explicitly trying to avoid that but still retain the underlying integrity that a FK will provide.
JPA 2 and I'm using EclipseLink.

JPA: Is it possible to persist child objects in the array only when the main object is persisted?

I am developing a web application using JSF and JPA(Eclipse link). I have two entities with bidirectional OneToMany relationship. The owner entity is contact and target entity is customer. Single customer can have multiple contacts, like email, phone, etc. When the end user is adding a new customer, he also adds the contacts straight away. There is a need to cancel the saving of a new customer, even after adding contacts to that customer. I tried to add that functionality, but failed in the following way.
Can that senario be achieved directly by persistence?
Contact Entity
....
public class Contact implements Serializable {
....
#ManyToOne
Customer customer;
....
Customer Entity
....
public class Customer implements Serializable {
....
#OneToMany(mappedBy = "customer")
private List<Contact> contacts;
....
Adding a new contact to Customer (current is an object of Customer class)
Contact contact = new Contact();
contact.setCustomer(current);
....
current.getInstitutionContacts().add(contact);
This works when the current is already a persisted one. If I tried to add a contact to yet to persist one, there is a java.lang.NullPointerException.
I can work around to achieve the functionality, but is there any way we can just collect the contacts to the array and persist them only when (and if only) the customer is persisted? By using cascade persist or lazy fetch, etc?
Sounds like you want Contacts to be Components, not Entities.
The difference is that an entity has it's own lifecycle; it lives outside the scope of its association, and deleting the parent does NOT necessarily have to delete the child. Also, if a child is an Entity, other classes can also have relationships with that child.
Components are completely bound to the parent. They automatically go away if the parent goes away. They cannot be referenced by other associations or by other Entities. It's like they are simple properties of the parent class.
The only caveat is that I don't know if all JPA implementations support having a collection of components.
See this documentation. Particularly the part that says: "You can also use association annotations in an embeddable object (ie #OneToOne, #ManyToOne, #OneToMany or #ManyToMany). To override the association columns you can use #AssociationOverride."
If the JPA implementation you are using does, you can use the #Embeddable annotation and #OneToMany
Edit: -- I also found info here http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Collections.

Controlling DDL generation in Toplink Essentials

I am having some trouble with the DDL generation of Toplink Essentials. I am developing a Glassfish 2.1 based application and use JPA for persistence.
I have an object graph where a parent entity of class A owns a set of entities of class B. Entites B come in several flavors which is modelled using inheritance. One such flavor is a composite entity class BC that bundles a set several other B entites. All entites B in a BC must also be owned by the same entity A as B. Note that not all entites B of an entity A have to be part of a composite BC, they can also be standalone.
So basically that maps to the following classes:
#Entity
class A {
#ManyToOne(mappedBy="owner", cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
Set<B> bs;
}
#Entity
#Inheritance
abstract class B {
#Id
long id;
#ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
A owner;
#ManyToOne(optional = true)
BC composite;
}
#Entity
class BC extends B {
#OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "composite")
Set<B> parts;
}
When toplink generates the DDL for this object hierarchy it creates all foreign key constraints as expected. However it does not set cascading rules for the constraints.
When I now try to delete an entire object graph via a reference to the A instance there can be situations where toplink fails to correctly remove the graph from the database. When toplink deletes a BC entity before deleting the contained B entities the foreign key constraint for the "composite" relationship is violated.
This situation can be corrected by manually adjusting the generated DDL to CASCADE (or SET NULL) on the relevant foreign key constraint which is fine for a production environment. This however fails in a test environment with in-memory (Derby) databases where DDL generation is managed entirely by toplink essentials and thus leads to the constraint violation described above.
Is there any way to influence the DDL generation process such that the required cascading rules are correctly set by toplink essentials?
Thanks for your help!
This is not an issue with DDL generation, but with deletion.
TopLink Essentials had some issues with resolving deletes from complex object graphs, or cyclic relationships. The are a few workarounds, such as deleting the dependent objects first and calling flush, then deleting the other objects, or setting the foreign key to null so they get updated. Using a customizer to mark the mapping privateOwned, or play with the constraint dependency may also work. You can also drop or defer the constraints.
All of the deletion issues have been fixed in EclipseLink, so upgrading the to latest EclipseLink release should resolve the issue.
EclipseLink also supports an #CascadeOnDelete annotation to add the cascade to the constraint in DDL generation.