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

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.

Related

Specifying One-to-one relationship foreign key in 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{
}

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 #EmbeddedId: How to update part of a composite primary key?

I have a many-to-many relationship where the link table has an additional property. Hence the link table is represented by an entity class too and called Composition. The primary key of Composition is an #Embeddable linking to the according entities, eg. 2 #ManyToOne references.
It can happen that a user makes an error when selecting either of the 2 references and hence the composite primary key must be updated. However due to how JPA (hibernate) works this will of course always create a new row (insert) instead of an update and the old Composition will still exist. The end result being that a new row was added instead of one being updated.
Option 1:
The old Composition could just be deleted before the new one is inserted but that would require that the according method handling this requires both the old and new version. plus since the updated version is actually a new entity optimistic locking will not work and hence last update will always win.
Option 2:
Native query. The query also increments version column and includes version in WHERE clause. Throw OptimisticLockException if update count is 0 (concurrent modification or deletion)
What is the better choice? What is the "common approach" to this issue?
Why not just change the primary key of Composition to be a UID which is auto-generated? Then the users could change the two references to the entities being joined without having to delete/re-create the Composition entity. Optimistic locking would then be maintained.
EDIT: For example:
#Entity
#Table(name = "COMPOSITION")
public class Composition {
#Id
#Column(name = "ID")
private Long id; // Auto-generate using preferred method
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn( .... as appropriate .... )
private FirstEntity firstEntity;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn( .... as appropriate .... )
private SecondEntity secondEntity;
....

JPA Composite Primary Key generating

I have simple entity class (irrelevant methods omitted):
#Entity
#Table(name="CONNECTIONS")
public class Connection implements Serializable {
#Id private Long id_track;
#Id private Long id_carrier;
#Id private Date date_out;
#Id private Time time_out;
private Date date_in;
private Time time_in;
private Double price;
...
}
I expect that JPA (in my case Eclipse implementation) creates TABLE CONNETIONS with composite primary key that consists of id_track, id_carrier, date_out and time_out columns but it adds addidional column id (of type integer) What do I do wrong?
I can not reproduce this. Are you sure JPA is creating your table?
Also ensure you have recompiled and redeployed your code.
Perhaps enable logging, and include what JPA provider and version you are using.
Are you using Glassfish?

Mapping xml to jpa entities using JAXB

Isn't it possible to map xml to jpa entities using JAXB? Will Eclipselink Moxy be helpful?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
Yes you can map JPA entities to XML, and the following are some ways that EclipseLink JAXB (MOXy) makes this easier.
1. Bidirectional Mappings
Customer
import javax.persistence.*;
#Entity
public class Customer {
#Id
private long id;
#OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
private Address address;
}
Address
import javax.persistence.*;
import org.eclipse.persistence.oxm.annotations.*;
#Entity
public class Address implements Serializable {
#Id
private long id;
#OneToOne
#JoinColumn(name="ID")
#MapsId
#XmlInverseReference(mappedBy="address")
private Customer customer;
}
For More Information
http://blog.bdoughan.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-25.html
2. Mapping Compound Key Relationships
We normally think of mapping a tree of objects to XML, however JAXB supports using the combination of #XmlID/#XmlIDREF to map relationship between nodes representing a graph. The standard mechanism is one key, to one foreign key. JPA supports the concept of composite keys and so does MOXy using #XmlKey and #XmlJoinNodes (similar to #XmlJoinColumns in JPA).
Employee
#Entity
#IdClass(EmployeeId.class)
public class Employee {
#Id
#Column(name="E_ID")
#XmlID
private BigDecimal eId;
#Id
#XmlKey
private String country;
#OneToMany(mappedBy="contact")
#XmlInverseReference(mappedBy="contact")
private List<PhoneNumber> contactNumber;
}
PhoneNumber
#Entity
public class PhoneNumber {
#ManyToOne
#JoinColumns({
#JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
#JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
#XmlJoinNodes( {
#XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
#XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})
private Employee contact;
}
For More Information
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA/CompoundPrimaryKeys
3. MOXy allows for Composite and Embedded Keys
JPA can also use embedded key classes to represent composite keys. MOXy also supports this style of composite keys.
For More Information
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA/EmbeddedIdClass
4. EclipseLink JAXB (MOXy) and EclipseLink JPA Have Shared Concepts
EclipseLink provides both JAXB and JPA implementations that share a common core. This means that they share many of the same concepts, such as:
Virtual Access Methods
EclipseLink supports the concept of virtual properties. This is useful when creating a multi-tenant application where you want per-tenant customizations. This concept is upported in both EclipseLink's JPA and JAXB implementations.
http://blog.bdoughan.com/2011/06/moxy-extensible-models-multi-tenant.html
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Extensibility