I am using Hibernate JPA. My sample entities are as follows:
Listing #1:
Code:
@XmlRootElement(name="department", namespace="http://mycompany.com/schema/entity/ut/ut-department/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(value=XmlAccessOrder.UNDEFINED)
@Entity
//....
public class DepartmentBean implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@DocumentId
@Column(name="department_id", nullable=false)
private Long id;
@XmlAttribute
@XmlID // Alternate key used as XmlID
@Column(name="dept_code", nullable=false)
@Field(store=Store.YES, analyze=Analyze.NO)
private String deptCode;
@XmlElement(name="employee", namespace="http://mycompany.com/schema/entity/ut/ut-employee/")
@XmlIDREF
//@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH})
@OneToMany(mappedBy="departmentRef", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
@ContainedIn
private List<EmployeeBean> employees = new ArrayList<>();
//... other fields & getters setters omitted for brevity
}
Listing #2:
Code:
@XmlRootElement(name="employee", namespace="http://mycompany.com/schema/entity/ut/ut-employee/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(value=XmlAccessOrder.UNDEFINED)
@Entity
//....
public class EmployeeBean implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="employee_id", nullable=false)
@DocumentId
//@Type(type = "objectid")
private Long id;
@XmlAttribute
@XmlID // Alternate key used as XmlID
@Column(name="employee_number", nullable=false)
@Fields({
@Field,
@Field(name="employeeNumber-sort", analyze=Analyze.NO, store=Store.YES)
})
private String employeeNumber;
@XmlElement
@XmlIDREF
@ManyToOne
@IndexedEmbedded(depth=1)
@Boost(value=0.5F)
private EmployeeBean manager;
@XmlElement(namespace="http://mycompany.com/schema/entity/ut/ut-department/")
@XmlIDREF
@ManyToOne
@JoinColumn(name="department_ref")
@IndexedEmbedded(depth=1)
private DepartmentBean departmentRef;
//... other fields & getters setters omitted for brevity
}
When I marshall a department and employee objects I get the following -
Listing #3:
Code:
<ns2:department deptCode="OPRTN" xmlns:ns2="http://mycompany.com/schema/entity/ut/ut-department/" xmlns:ns3="http://mycompany.com/schema/entity/ut/ut-employee/">
<id>1813</id>
<deptName>MyCompany Operations</deptName>
<description>MyCompany Operations</description>
<ns3:employee>A12758</ns3:employee>
<ns3:employee>A11538</ns3:employee>
</ns2:department>
Listing #4:
Code:
<ns3:employee employeeNumber="A11538" xmlns:ns2="http://mycompany.com/schema/entity/ut/ut-department/" xmlns:ns3="http://mycompany.com/schema/entity/ut/ut-employee/">
<id>1822</id>
<firstName>Some</firstName>
<lastName>Guy</lastName>
<nickName>SomeGuy</nickName>
<dateOfJoning>2013-03-01T05:30:00+05:30</dateOfJoning>
<email>SomeGuy@mycompany.com</email>
<manager>A12758</manager>
<ns2:departmentRef>OPRTN</ns2:departmentRef>
</ns3:employee>
Quote:
However when I use the same xml (as in above) and try to un-marshall, the reference fields in the resultant entity objects come as null. For example in the EmployeeBean , the "departmentRef" field becomes null.
I have use cases involving both marshalling and un-marshalling.
1. Certain webservices e.g. "public List<EmployeeBean> findByDepartment(String deptCode)" . Here I need to break the cyclic object graph to facilitate marshalling.
2. File based loader where the input will be similar to listing #4. I need to un-marshall the objects properly without loosing the foreign / self references.
I understand that XmlIDREF needs the XmlID to be present within the same xml document context. That is perhaps the reason, why the references are becoming null. I see eclipselink has @XmlInverseReference to circumvent such issues. Is there any Hibernate equivalent ?
What are the other possible solutions ?
Thanks in advance for your attention and help.