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
Related
If I have a table like this :
Client
private Long int;
private String name;
#ManyToOne(mappedBy="otherField")
private Address addresses;
And I Create a repository that extends JPA Repository. Given the name of the client, I want to get as results also the Address Table fields.
Using the method
Client findByName(String name)
Will my this also return all the fields that are on the Address Table ?
Like:
Address
private Long id;
private String city;
private Int code;
private String street;
From the docs
The Hibernate recommendation is to statically mark all associations
lazy and to use dynamic fetching strategies for eagerness. This is
unfortunately at odds with the JPA specification which defines that
all one-to-one and many-to-one associations should be eagerly fetched
by default. Hibernate, as a JPA provider, honors that default.
So Hibernate behaves the same as JPA:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
Also take a look at the JPA sepcifications here.
working with OpenJPA2 persistence. I have a very simple entity class, that does have a String property and a List property. I do persist its instances flawlessly with the nested List (in a JSF2 web project). I check the database and there appears two tables (I use automatic schema generation), one for the entity itself, and other table for the nested List. All data persisted using EntityManager is stored fine on both tables.
Problem is I cannot retrieve nested data. I mean, I do a Query for getting all instances of the entity, but the List of all instances come empty.
(DB Engine is MySQL. ORM is OpenJPA2. Server is TomEE 1.6. IDE is Netbeans 8. I use automatic schema generation, so I DO NOT WANT to design the database tables, and I DO WANT to let the ORM create the tables, so I can work purely with objects and forget about DB.)
following is Entity Class code:
#Entity
public class Cliente implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nombre;
#ElementCollection
private List<String> emails = new ArrayList<String>();
// getters and setters omitted for brevity.
It does have an associated Facade Class, which is ClienteFacade. It includes the getAll method which uses a JPQL Query.
public List<Cliente> listaClientes(){
Query query = em.createQuery("SELECT c FROM Cliente c");
return query.getResultList(); }
Problem is, I get all instances of the entity in a List, but all lists of List emails come out empty. I think problem may be in the JPQL query. Still trying to learn JPQL with some difficulty... so please, How can I retrieve the nested data with JPQL?
Many thanks!
Try #ElementCollection(fetch = FetchType.EAGER) because the default type is lazy. That means that the lists are not loaded directly.
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.
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.
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?