How to map entity with JPA? - jpa-2.0

I can't get the right mapping for the field tree in this class:
#Entity
#Table(name = "SushiMapTree")
public class SushiMapTree<K, V> extends Persistable implements Map<K,V> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="SushiMapID")
protected int ID;
#OneToOne(cascade = CascadeType.ALL)
#JoinTable(name="SushiMapTree_SushiTree")
private SushiTree<SushiMapElement<K, V>> tree = new SushiTree<SushiMapElement<K,V>>();
This are the other classes and their mappings:
#Entity
#Table(name = "SushiTree")
public class SushiTree<T> extends Persistable implements Collection<T> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="SushiTreeID")
protected int ID;
#Column(name="Test")
private String test = "Test";
#OneToMany(cascade = CascadeType.PERSIST)
#JoinTable(name="SushiTree_SushiTreeElements")
private List<SushiTreeElement<T>> treeElements = new ArrayList<SushiTreeElement<T>>();
#OneToMany(cascade = CascadeType.PERSIST)
#JoinTable(name="SushiTree_SushiTreeRootElements")
private List<SushiTreeElement<T>> treeRootElements = new ArrayList<SushiTreeElement<T>>();
}
#Entity
#Table(name = "SushiMapElement")
public class SushiMapElement<K, V> extends Persistable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int ID;
#ManyToOne(cascade = CascadeType.PERSIST)
private SushiMapElement<K, V> parent;
#OneToMany(cascade = CascadeType.PERSIST)
private List<SushiMapElement<K, V>> children = new ArrayList<SushiMapElement<K, V>>();
#Column(name = "MapKey")
K key;
#Column(name = "MapValue")
V value;
The other classes work well, but I can't get the right mapping. I tried different mappings for some hours with Column, JoinColumn, JoinTable and so on. Eclipse Link does not create the database and says to use a ValueHolderInterface:
The attribute [tree] is not declared as type ValueHolderInterface, but its mapping uses indirection.
Thanks for your help!

I solved the problem with the following annotation:
#ManyToOne(cascade=CascadeType.PERSIST)
#JoinColumn(name="TreeID")
But I don't know, why it work this way.

Related

Hibernate criteria cannot fetch rows could not resolve property

Hi i have these 2 basic entity mapping for postgresql db, and i have wrote criteria for
fetching all activated user which have same key it is showing this error
org.hibernate.QueryException: could not resolve property: key.id of: com.sar.dfsapp.modal.ActivatedUser
#Entity
#Table(name = "activated_user")
public class ActivatedUser implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, length = 11)
private long id;
#ManyToOne
#JoinColumn(name = "key_id", nullable = false)
private Key key;
}
#Entity
#Table(name = "key")
public class Key implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, length = 11)
private long id;
#Column(name = "key_code", nullable = false)
private String keyCode;
}
Below is my criteria i have tried.
Criteria c = getSession().createCriteria(ActivatedUser.class);
c.add(Restrictions.eq("key.id", id));
List<ActivatedUser> result = c.list();
try this :
Criteria c = getSession().createCriteria(ActivatedUser.class);
Criteria keyCriteria = criteria.createCriteria("key", CriteriaSpecification.INNER_JOIN);
keyCriteria.add(Restrictions.eq("id", id));
List<ActivatedUser> result = c.list();
it there the same error ?

JPA query filtered by a collection's property in a OneToMany relationship

hope somebaody can help me. I have two entities related OneToMany.
First:
#Entity
#Table(name = "repartos")
#XmlRootElement
public class Repartos implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Column(name = "fecha")
#Temporal(TemporalType.DATE)
private Date fecha;
#OneToMany(cascade = {CascadeType.ALL}, mappedBy = "repartoId")
public List<RepartosDetalle> repartosDetalleList;
.....
And then the another one:
#Entity
#Table(name = "repartos_detalle")
#XmlRootElement
public class RepartosDetalle implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#JoinColumn(name = "reparto_id", referencedColumnName = "id")
#ManyToOne(optional = false)
private Repartos repartoId;
#Column(name = "descargado")
#Convert(converter = BooleanOneZeroConverter.class)
private boolean descargado;
public RepartosDetalle() {
}
public RepartosDetalle(Repartos repartoId) {
this.repartoId = repartoId;
}
public Repartos getRepartoId() {
return repartoId;
}
public void setRepartoId(Repartos repartoId) {
this.repartoId = repartoId;
}
public boolean isDescargado() {
return descargado;
}
public void setDescargado(boolean descargado) {
this.descargado = descargado;
}
}
What I try to get is all the Repartos given a date and where they have al least one RepartosDetalle with the property descargado=TRUE.
I've been trying with the following query but I do't get any result.
#Override
public List<Repartos> buscarPorFechaDescargados(Date searchDate) {
Query q = em.createQuery("SELECT e FROM Repartos e "
+ "WHERE e.fecha = :searchDate"
+ " AND e.repartosDetalleList.descargado=TRUE");
q.setParameter("searchDate", searchDate);
return q.getResultList();
}
Is there a proper way to make this query using one of the collection's property value?
Thanks a lot and nice weekend.
Try to use JOIN operator on these 2 entities - Repartos and RepartosDetalle :
SELECT e FROM Repartos e JOIN RepartosDetalle d
WHERE e.fecha = :searchDate
AND d.descargado = TRUE

Marshalling Error: failed to lazily initialize a collection of role (...), no session or session was closed

I`m using Eclipse RCP with EJB exposed like WebServices. My services beans looks like follows
#Override
#SuppressWarnings("unchecked")
public List<Author> listAll() {
final Query query = this.entityManager.createQuery("from Author");
final List<Author> authors = query.getResultList();
return authors;
}
The two entityes are:
#Entity
#Table(name = "books")
public class Book implements Serializable {
#Id
private int id;
private String title;
private String summary;
private String isbn;
#Column(name = "published")
private Date publishingDate;
#Column(name = "created")
private Date createdAt;
#Column(name = "updated")
private Date modifiedAt;
#ManyToMany
#JoinTable(
name = "book_authors",
joinColumns = #JoinColumn(name = "book_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "author_id", referencedColumnName = "id"))
private List<Author> authors;
and
#Entity
#Table(name = "authors")
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "middle_name")
private String middleName;
#Column(name = "last_name")
private String lastName;
#Column(name = "created")
private Date createdAt;
#Column(name = "updated")
private Date modifiedAt;
#ManyToMany
#JoinTable(
name = "book_authors",
joinColumns = #JoinColumn(name = "author_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "book_id", referencedColumnName = "id"))
private List<Book> books;
In my TestWSCLient i`m trying to do something like this
AuthorServiceBeanServiceLocator locator = new AuthorServiceBeanServiceLocator();
AuthorServiceBean service = locator.getAuthorServiceBeanPort();
Author[] authors = service.listAll();
for(Author a : authors){
System.out.println(a.getFirstName());
}
and I`m getting this error
{....//xml.apache.org/axis/}stackTrace:Marshalling Error: failed to lazily initialize a collection of role: ro.cgs.entities.Author.books, no session or session was closed
I`m mention that if I do not make the Many-To-Many relationship all works fine. Can anybody tell me what should I do to fix this problem ?
I use Hibernate for persistence.
Thanks.

JPA StackOverflowError when loading data in relationship tables

I'm trying to implement loading in three tables (the beginning of the problem with mapping)
Products:
#Entity
#Table(name = "products")
public class Product implements Serializable {
#Id
#Column(name = "id")
private Integer id;
#OneToMany(mappedBy = "property", fetch = FetchType.LAZY)
private Collection<ProductProperty> productPropertyCollection;
...
}
Properties:
#Entity
#Table(name = "properties")
public class Property implements Serializable {
#Id
#Column(name = "id")
private Integer id;
#OneToMany(mappedBy = "property", fetch = FetchType.LAZY)
private Collection<ProductProperty> productPropertyCollection;
...
}
Product_Property
#Entity
#Table(name = "product_property")
public class ProductProperty implements Serializable {
#EmbeddedId
protected ProductPropertyPK productPropertyPK;
#MapsId(value = "propertyId")
#JoinColumn(name = "property_id", referencedColumnName = "id")
#ManyToOne()
private Property property;
#MapsId(value = "productId")
#JoinColumn(name = "product_id", referencedColumnName = "id")
#ManyToOne()
private Product product;
...
}
#Embeddable
public class ProductPropertyPK implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "product_id", insertable = false, updatable = false)
private int productId;
#Basic(optional = false)
#NotNull
#Column(name = "property_id", insertable = false, updatable = false)
private int propertyId;
...
}
It works fine for 1, 10, 100 products, but somewhere there is an error, because for 1000 and more products throws error:
Caused by: java.lang.StackOverflowError
at java.util.HashMap.getEntry(HashMap.java:443)
at java.util.HashMap.containsKey(HashMap.java:434)
at java.util.HashSet.contains(HashSet.java:201)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4141)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:938)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:916)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.CollectionMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(CollectionMapping.java:426)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:938)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:916)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.CollectionMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(CollectionMapping.java:426)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:938)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectReferenceMapping.java:916)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:1964)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4178)
...
when i'm creating ProductProperty, i'm setting product and property in ProductProperty, and adding to collection for bidirection in Product and Property.
where i could make a mistake?
Looks like your object model complexity or depth is just difficult to traverse within your JVM's stack limits. As it is, every entity seems reachable from every other entity, which causes problems when traversed recursively. Try increasing the -Xss setting. You might also reduce the interconnectivity, such as removing one of the OneToMany mappings and query for it directly instead of storing it in the Product or Property mapping. You might also file an enhancement with EclipseLink to traverse the object graph using a stack instead of recursively.

Why can't I instantiate a managedbean in jpa?

I am trying to develop a small web application as training for my upcoming finals and I can't figure out what I'm doing wrong.
These are my *Entities*L Kunde and Konto (many2many-relationship), the auto-created table Kunde_Konto has only the two primary keys of my entities.
#Entity
#NamedQueries({
#NamedQuery(name="findKundeById", query="select k from Kunde k where k.svnr = :svnr"),
})
public class Kunde implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(precision=4, scale=0)
private Long svnr;
#ManyToMany
private List<Konto> konten;
}
#Entity
#NamedQueries({
#NamedQuery(name="findKontoByBesitzer", query="select k from Konto k join k.besitzer b where b.svnr = :svnr")
})
public class Konto implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(precision=4, scale=0)
private Long knr;
#ManyToMany(mappedBy="konten")
private List<Kunde> besitzer;
}
And this is my Managed Bean:
#ManagedBean
#SessionScoped
public class KundenKontoList implements Serializable {
private FacesContext fc = null;
private HttpServletRequest hsr = null;
private HttpSession hs = null;
#EJB
private KontoFacadeLocal kontoFacade;
#EJB
private KundeFacadeLocal kundeFacade;
private Kunde k;
private List<Konto> konten;
/**
* Creates a new instance of KundenKontoList
*/
public KundenKontoList() {
fc = FacesContext.getCurrentInstance();
hsr = (HttpServletRequest) fc.getExternalContext().getRequest();
hs = hsr.getSession();
k = (Kunde) hs.getAttribute("kunde");
konten = kontoFacade.findKontoByBesitzer(k);
}
}
The exception
com.sun.faces.mgbean.ManagedBeanCreationException: Klasse at.pf.controller.KundenKontoList kann nicht instanziiert werden.
which translated means that KundenKontoList can't be instatiated, is thrown at the line:
konten = kontoFacade.findKontoByBesitzer(k);
//method in the facade:
#Override
public List<Konto> findKontoByBesitzer(Kunde k) {
Query q = em.createNamedQuery("findKontoByBesitzer");
q.setParameter("svnr", k.getSvnr());
return q.getResultList();
}
I think that it has something to do with the kontoFacade, but I don't know what the exact problem is.
Fail on init of managedbean, suggests to me that injection of ejbs is failing. Is there a longer error message?