I have 2 Embeddable objects and 1 Entity object. I want to use first Embeddable object inside another. Currently its not working for me. Below is the code
Class 1
#Embeddable
public class Object1{
public Object1{
}
#Column(name = "name")
String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
Class 2
#Embeddable
public class Object2{
public Object2{
}
#Column(name = "name")
String name;
#Embedded
#Column(name = "object1")
Object1 object1;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Object1 getObject1(){
return object1;
}
public void setObject1(Object1 object1){
this.object1 = object1;
}
}
Entity Class
#Entity
#Table(name = "xxx", schema = "yyy#zzz")
public void EC{
public EC(){
}
#Embedded
#Column(name = "object2")
Object2 object2;
public Object2 getObject2(){
return object2;
}
public void setObject2(Object2 object2){
this.object2 = object2;
}
}
When I run this program, only name of Object2 is getting saved but not the embedded Object1
Is this structure is possible in Kundera? Or what am I doing wrong?
allowed only for Cassandra's composite partition key
-Vivek
Related
Need make a relationship between same table. Example: the object "category" have subcategories and the subcategorie have other subcategorie.
In MySQL make a column and point to primary key of same table, but, howto make in JPA?
My code is:
#Entity
#Table(name = "objects")
public class JObject {
private long id;
private String name;
private JObject parentJObject;
private Set<JObject> jObjects;
public JObject(){
}
public JObject(long id){
this.id = id;
}
public JObject(String name){
this.name = name;
}
public JObject(String name, JObject parentJObject){
this.name = name;
this.parentJObject = parentJObject;
}
#Null
#JoinColumn(name="parent_object_id", referencedColumnName="id")
#ManyToOne(cascade=CascadeType.ALL)
public JObject getParentJObject() {
return parentJObject;
}
public void setParentJObject(JObject parentJObject) {
this.parentJObject = parentJObject;
}
#Null
#OneToMany(mappedBy = "parentJObject", cascade = CascadeType.ALL)
public Set<JObject> getJObjects() {
return jObjects;
}
public void setJObjects(Set<JObject> jObjects) {
this.jObjects = jObjects;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#NotNull
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And the making objects:
JObject jObjectcategories = new JObject("Demo 1");
Set categoriesJObjects = new HashSet<JObject>(){{
add(new JObject("Demo 1.1", jObjectcategories));
}};
jObjectcategories.setJObjects(categoriesJObjects);
jObjectDao.save(new HashSet<JObject>() {{
add(jObjectcategories);
}});
But does not works. The log says:
List of constraint violations:[ ConstraintViolationImpl{interpolatedMessage='It has to be null', propertyPath=JObjects, rootBeanClass=class a.b.c.models.JObject, messageTemplate='{javax.validation.constraints.Null.message}'} ]
You need to be consistent in where you place your JPA annotations: either all on fields, or all on getters. But not mixed as you're doing.
The OneToOne should be a ManyToOne according to your description, since several objects share the same parent.
And the cascade ALL doesn't make sense: you don't want to delete a parent when a child is deleted.
How can I implement a bidirectional one-to-one mapping using Google Application Engine (GAE) using Java Data Objects (JDO)?
I have a User class which holds contactInfo object and a ContactInfo class that holds a user object
#PersistenceCapable(identityType ="APPLICATION", detachable = "true")
public class User{
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
private String name;
#Persistent(dependent = "true")
private ContactInfo child;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ContactInfo getChild() {
return child;
}
public void setChild(ContactInfo child) {
this.child = child;
}
}
#PersistenceCapable(identityType ="APPLICATION", detachable = "true")
public class ContactInfo {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key id;
#Persistent(mappedBy = "child")
private User parent;
private String contactDetail;
public Key getId() {
return id;
}
public void setId(Key id) {
this.id = id;
}
public String getContactDetail() {
return contactDetail;
}
public void setContactDetail(String contactDetail) {
this.contactDetail = contactDetail;
}
}
Following error i am getting while testing API from API explorer
com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.demo.jdo.ContactInfo[\"user\"]->com.demo.jdo.User[\"contactInfo\"]->com.demo.jdo.ContactInfo[\"user\"]-
Standard JDO 1-1 bidir is simply found from http://www.datanucleus.org/products/accessplatform_3_1/jdo/orm/one_to_one.html#bi
GAE ought to be no different in this respect; last time I used it (maybe 3 yrs ago) they had some tests, think those under here http://code.google.com/p/datanucleus-appengine/source/browse/#svn%2Ftrunk%2Ftests%2Fcom%2Fgoogle%2Fappengine%2Fdatanucleus
Your question provides no definition of what you have tried in terms of annotations
Got the Solution, problem was with wrong use of mappedBy & presence of getter and setter of parent object in child.
#Persistent(mappedBy = "") annotation should only be at non-owner side
In on-owner/ child side there should not be any getter/setter present for owner/parent object.
Working code:
User.java
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
#PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class User {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
private String name;
#Persistent(dependent = "true")
private ContactInfo contactInfo;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ContactInfo getContactInfo() {
return contactInfo;
}
public void setContactInfo(ContactInfo contactInfo) {
this.contactInfo = contactInfo;
}
}
ContactInfo.java
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Key;
#PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class ContactInfo {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key id;
#Persistent(mappedBy = "contactInfo")
/*
* Important: Do not create getter and setters for this object else
* bidirectional mapping gives error
*/
private User user;
private String contactDetail;
public Key getId() {
return id;
}
public void setId(Key id) {
this.id = id;
}
public String getContactDetail() {
return contactDetail;
}
public void setContactDetail(String contactDetail) {
this.contactDetail = contactDetail;
}
}
I have one exception, which yold what I have no mapping on table. But I have this
Exeption is : \
AnnotationException: mappedBy reference an unknown target entity property: Relative.people in Person.relations
Relative entity is here:
#Entity
#Table(name = "relation")
public class Relative extends AbstractModel<UUID> implements Model<UUID> {
private UUID id;
private Person person;
private RelationTypeEnum relation;
public Relative() {
}
#Override
public void assignId() {
id = UUID.randomUUID();
}
#Override
#Id
#Column(name = "id")
public UUID getId() {
return id;
}
#ManyToOne
#JoinColumn(name="person_id", nullable=false)
public Person getPerson() {
return person;
}
#Column(name = "relation")
public RelationTypeEnum getRelation() {
return relation;
}
public void setId(UUID id) {
this.id = id;
}
public void setPerson(Person person) {
this.person = person;
}
public void setRelation(RelationTypeEnum relation) {
this.relation = relation;
}
}
And Person entity is here:
#Entity
#Table(name = "people")
public class Person extends AbstractModel<UUID> implements Model<UUID> {
private UUID id;
private String name;
private List<Relative> relations;
#Override
public void assignId() {
id = UUID.randomUUID();
}
#Override
#Id
#Column(name = "id")
public UUID getId() {
return id;
}
#Column(name = "name")
public String getName() {
return name;
}
#OneToMany(targetEntity=Relative.class, cascade=CascadeType.ALL,
mappedBy="people")
public List<Relative> getRelations() {
return relations;
}
public void setId(UUID id) {
this.id = id;
}
public void setName(String username) {
this.name = username;
}
public void setRelations(List<Relative> relations) {
this.relations = relations;
}
}
Solved.
Just changed
#Table(name = "people")
to
#Table(name = "person")
In my case there was a project which included a copy of the jar causing this issue. It was a web project which is including the jar inside its lib i.e. 2 copies of the same jar one with a different class version. Only discovered this when I physically opened the main ear and found the 2nd jar inside a web project.
I'm trying to do a database lookup using JPA with EclipseLink. My database is Oracle 11.2.0. I have the following entity classes defined:
#Entity
#Table(name = "BS_PROVIDERS")
public class BsProvider {
#Id
#Column(name = "GUID")
private String guid;
public String getGuid() { return guid; }
public void setGuid(String guid) { this.guid = guid; }
#Column(name = "NAME")
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
#Entity
#Table(name = "CP_PROVIDERS")
public class CpProvider{
#Id
#Column(name = "GUID")
private String guid;
public String getGuid() { return guid; }
public void setGuid(String guid) { this.guid = guid; }
#Column(name = "NAME")
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
#NamedQueries({
#NamedQuery(
name = Catalog.FIND_BY_CPP_AND_BSP,
query = "select c from Catalog c where (c.cpProvider = :cpProvider) and ( (:bsProvider IS NULL) or (c.bsProvider = :bsProvider))"
)
})
#Entity
#Table(name = "CATALOGS")
public class Catalog {
public static final String FIND_BY_CPP_AND_BSP = "Catalog.findByCppAndBsp";
public static final String CP_PROVIDER_PARAM = "cpProvider";
public static final String BS_PROVIDER_PARAM = "bsProvider";
#Id
#Column(name = "GUID")
private String guid;
public String getGuid() { return guid; }
public void setGuid(String guid) { this.guid = guid; }
#Column(name = "NAME")
private String name;
public String getName() { return name; }
public void setName() { this.name = name; }
#ManyToOne
#JoinColumn(name = "CPP_GUID")
private CpProvider cpProvider;
public CpProvider getCpProvider() { return cpProvider; }
public void setCpProvider(CpProvider cpProvider) { this.cpProvider = cpProvider; }
#ManyToOne()
#JoinColumn(name = "BSP_GUIG")
private BsProvider bsProvider;
public BsProvider getBsProvider() { return bsProvider; }
public void setBsProvider(BsProvider bsProvider) { this.bsProvider = bsProvider; }
}
Code that creates the query and sets the parameters:
TypedQuery<Catalog> catalogQuery = em.createNamedQuery(Catalog.FIND_BY_CPP_AND_BSP, Catalog.class);
catalogQuery.setParameter(Catalog.CP_PROVIDER_PARAM, cpProvider);
catalogQuery.setParameter(Catalog.BS_PROVIDER_PARAM, bsProvider);
List<Catalog> catalogList = catalogQuery.getResultList();
When the variable bsProvider is NULL, all parameters are registerd are registerd correctly according to the EclipseLink log:
SELECT GUID, NAME, BSP_GUIG, CPP_GUID FROM CATALOGS WHERE ((CPP_GUID = ?) AND ((? IS NULL) OR (BSP_GUIG = ?)))
bind => [18EC0EDB-21A4-4845-960A-D5D2BDAC7B87, null, null]
Otherwise when the variable bsProvider refers to an existing entity I get the following exception:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Invalid column type
Error Code: 17004
Call: SELECT GUID, NAME, BSP_GUIG, CPP_GUID FROM CATALOGS WHERE ((CPP_GUID = ?) AND ((? IS NULL) OR (BSP_GUIG = ?)))
bind => [18EC0EDB-21A4-4845-960A-D5D2BDAC7B87, com.bssys.ebpp.dbaccess.model.BsProvider#5dbbe8df, 44E8F4BF-CFDC-49DB-AB0B-718C72D6B4EF]
As you can see the first and the third parameters are bound correctly (they are replaced by the primary key values), but the second is not. What's the reason of such a strange behavior?
I want to copy the entity's UUID, generated at run time to another field.
The entity id is generated via the code described bellow:
package eclipselink.example;
public class UUIDSequence extends Sequence implements SessionCustomizer {
public UUIDSequence() {
super();
}
public UUIDSequence(String name) {
super(name);
}
#Override
public Object getGeneratedValue(Accessor accessor,
AbstractSession writeSession, String seqName) {
return UUID.randomUUID().toString().toUpperCase();
}
...
public void customize(Session session) throws Exception {
UUIDSequence sequence = new UUIDSequence("system-uuid");
session.getLogin().addSequence(sequence);
}
}
Persitence.xml:
property name="eclipselink.session.customizer" value="eclipselink.example.UUIDSequence"
The entity:
public abstract class MyEntity{
private String id;
private String idCopy;
#Id
#Basic(optional = false)
#GeneratedValue(generator="system-uuid")
#XmlElement(name = "ID")
public String getId() {
return id;
}
}
How can I instruct JPA (Eclipse-link) to copy the UUID generated at runtime to idCopy field as well?
I'm not 100% sure this will work (I don't know if EclipseLink calls the setter or assigns the field directly), but give this a try:
public abstract class MyEntity{
private String id;
private String idCopy;
#Id
#Basic(optional = false)
#GeneratedValue(generator="system-uuid")
#XmlElement(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
this.idCopy = id;
// or
// this.setIdCopy(id);
}
}