Mapping issue on Hibernate - java

I am in the middle of developing a JHipster project and I've come to a halt due to what I believe to be mapping issues
My Database has several tables, but the two that affect me here are Study and Publication, where they have a Many to Many relationship.
I need to retrieve the collection of Publications where a study can be published, hence Study is the owner of the relationship, but for some reason, Hibernate don't recognise the attributes I map the relation with.
All of this started trying to solve a lazy connection issue, yes I have been through most posts relating this and I have tried everything that made sense to me.
Here the code of Study:
#Audited
#Entity
#Table(name = "Study")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "study")
public class Study implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "num_sites")
private Integer numSites;
#Column(name = "ref")
private String ref;
#Column(name = "study_type")
private String studyType;
#ManyToMany(fetch = FetchType.LAZY)
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#JoinTable(name = "Pub_Study",
joinColumns = #JoinColumn(name="studies_id", referencedColumnName="id"),
inverseJoinColumns = #JoinColumn(name="publications_id", referencedColumnName="id"))
public static Set<Publication> publications = new HashSet<>();
#OneToMany(mappedBy = "study")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<SiteData> siteDatas = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getNumSites() {
return numSites;
}
public void setNumSites(Integer numSites) {
this.numSites = numSites;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getStudyType() {
return studyType;
}
public void setStudyType(String studyType) {
this.studyType = studyType;
}
public static Set<Publication> getPublicationss() {
return publications;
}
public void setPublicationss(Set<Publication> publications) {
this.publications = publications;
}
public Set<SiteData> getSiteDatas() {
return siteDatas;
}
public void setSiteDatas(Set<SiteData> siteDatas) {
this.siteDatas = siteDatas;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Study study = (Study) o;
if(study.id == null || id == null) {
return false;
}
return Objects.equals(id, study.id);
}
#Override
public int hashCode() {
return Objects.hashCode(id);
}
#Override
public String toString() {
return "Study{" +
"id=" + id +
", numSites='" + numSites + "'" +
", ref='" + ref + "'" +
", studyType='" + studyType + "'" +
'}';
}
Here the code of Publication:
#Audited
#Entity
#Table(name = "Publication")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "publication")
public class Publication implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "authors")
private String authors;
#Column(name = "first_author")
private String firstAuthor;
#Column(name = "journal")
private String journal;
#Column(name = "pubMedId")
private Integer pubMedId;
#Column(name = "title")
private String title;
#Column(name = "year_publish")
private Integer yearPublish;
#Version
Integer version;
#ManyToMany(fetch = FetchType.LAZY)
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Study> studies = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAuthors() {
return authors;
}
public void setAuthors(String authors) {
this.authors = authors;
}
public String getFirstAuthor() {
return firstAuthor;
}
public void setFirstAuthor(String firstAuthor) {
this.firstAuthor = firstAuthor;
}
public String getJournal() {
return journal;
}
public void setJournal(String journal) {
this.journal = journal;
}
public Integer getPubMedId() {
return pubMedId;
}
public void setPubMedId(Integer pubMedId) {
this.pubMedId = pubMedId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getYearPublish() {
return yearPublish;
}
public void setYearPublish(Integer yearPublish) {
this.yearPublish = yearPublish;
}
public Set<Study> getStudies() {
return studies;
}
public void setStudies(Set<Study> studys) {
this.studies = studys;
}
public Integer getVersion(){
return version;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Publication publication = (Publication) o;
if(publication.id == null || id == null) {
return false;
}
return Objects.equals(id, publication.id);
}
#Override
public int hashCode() {
return Objects.hashCode(id);
}
#Override
public String toString() {
return "Publication{" +
"id=" + id +
", authors='" + authors + "'" +
", firstAuthor='" + firstAuthor + "'" +
", journal='" + journal + "'" +
", pubMedId='" + pubMedId + "'" +
", title='" + title + "'" +
", yearPublish='" + yearPublish + "'" +
'}';
}
}
Here the Implementation of the query from the Repository package:
public class SiteDataRepositoryImpl implements SiteDataRepositoryCustom{
#PersistenceContext
private EntityManager em;
#Override
public List <SiteDataViewDTO> searchSiteDataByFilter(List<Filter> listFilters) {
TypedQuery<SiteData> query = buildQuery(listFilters);
Hibernate.initialize(Study.publications);
int count=0;
for (Filter filter: listFilters){
if("country".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("category".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("studyRef".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("studyType".equals(filter.getName()))
query.setParameter(filter.getName(), filter.getQuery());
else if("pubMedId".equals(filter.getName()))
query.setParameter(filter.getName(), Integer.valueOf(filter.getQuery()));
count++;
}
List<SiteData> siteDataList = query.getResultList();
List<SiteDataViewDTO> siteDataViewDTOList=new ArrayList<SiteDataViewDTO>();
//temp variables
List<String>tempListTreatments = new ArrayList<String>();
List<String>tempListTitles = new ArrayList<String>();
List<Integer>tempListIdMed = new ArrayList<Integer>();
//filling SiteDataViewDTO list
siteDataList.stream().forEach(sd->{
SiteDataViewDTO temp = new SiteDataViewDTO();
temp.setTypeStudy(sd.getTypeStudy() + "id SiteData: " + sd.getId());
temp.setRef(sd.getStudy().getRef());
temp.setCategory(sd.getCategory().getName());
temp.setUpper95CI(sd.getUpper95CI());
temp.setYearStart(sd.getYearStart());
temp.setYearEnd(sd.getYearEnd());
Set<Publication>setPu = sd.getStudy().getPublicationss();
System.out.println("#################### In the query, size of the Publications List "+setPu.size());
setPu.stream().forEach(sp-> {
tempListTitles.add(sp.getTitle());
tempListIdMed.add(sp.getPubMedId());
});
Set<Treatment>setTr = sd.getTreatments();
/*setTr.stream().forEach(sp-> {
tempListTreatments.add(sp.getTreatmentName());
});*/
temp.setListPubObject(setPu);
temp.setListTreatObject(setTr);
siteDataViewDTOList.add(temp);
});
return siteDataViewDTOList;
}
private TypedQuery<SiteData> buildQuery(List<Filter> listFilters){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SiteData> cq = cb.createQuery(SiteData.class);
Root<SiteData> siteData = cq.from(SiteData.class);
Join<SiteData, Category> cat = siteData.join("category", JoinType.LEFT);
Join<SiteData, Location> loc = siteData.join("location",JoinType.LEFT);
Join<SiteData, Treatment> tre = siteData.join("treatments",JoinType.LEFT);
Join<SiteData, Study> stu = siteData.join("study",JoinType.LEFT);
Join<Study, Publication> pub = stu.join("publications",JoinType.LEFT);
List<Predicate> predicates = new ArrayList<>();
int index = 0;
for(Filter filter : listFilters){
if("country".equals(filter.getName()))
predicates.add(cb.equal(loc.get("country"), cb.parameter(String.class, filter.getName())));
else if("category".equals(filter.getName()))
predicates.add(cb.equal(cat.get("name"), cb.parameter(String.class, filter.getName())));
else if("studyRef".equals(filter.getName()))
predicates.add(cb.equal(stu.get("ref"), cb.parameter(String.class, filter.getName())));
else if("studyType".equals(filter.getName()))
predicates.add(cb.equal(stu.get("studyType"), cb.parameter(String.class, filter.getName())));
else if("pubMedId".equals(filter.getName()))
predicates.add(cb.equal(pub.get("pubMedId"), cb.parameter(Integer.class, filter.getName())));
index++;
}
cq.where(cb.and(predicates.toArray(new Predicate[0])));
return em.createQuery(cq);
}
}
So, if anyone could throw some light on to this, it would be very helpful!
I Edit to add the main exception it throws:
Caused by: org.hibernate.QueryException: could not resolve property: publications of: org.wwarn.vivax.manager.domain.Study
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)

You have a typo in your entity definition: "publicationss" instead of "publications". Since Hibernate uses JavaBeans properties for data access, it complains about getPublications() loss in your definition.
Metamodel preserves you from such typos, consider using it.

Related

org.hibernate.AnnotationException: mappedBy reference an unknown target entity property. There is an error: java.lang.NullPointerException

I am working with hibernate currently to try and map to and from SQL.
Every time I try to run my code I get the error:
org.hibernate.AnnotationException: mappedBy reference an unknown
target entity property: Catalog.primaryKey.suppliers in
Suppliers.catalogSet There is an error:java.lang.NullPointerException
I have triple checked to make sure I am mapping everything correctly, but I have to be missing something. Does anyone know why I would be getting a null pointer with my given code? These are my class codes:
import javax.persistence.*;
#Entity
#Table(name = "catalog")
#AssociationOverrides({
#AssociationOverride(name = "primaryKey.suppliers",
joinColumns = #JoinColumn(name = "sid")),
#AssociationOverride(name = "primaryKey.parts",
joinColumns = #JoinColumn(name = "pid"))
})
public class Catalog {
//Composite ID
private CatalogId primaryKey = new CatalogId();
//Additional Column
private String cost;
#EmbeddedId
public CatalogId getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(CatalogId primaryKey) {
this.primaryKey = primaryKey;
}
#Transient
public Suppliers getSuppliers(){
return getPrimaryKey().getSupplier();
}
public void setSuppliers(Suppliers supplier){
getPrimaryKey().setSupplier(supplier);
}
#Transient
public Parts getParts(){
return getPrimaryKey().getParts();
}
public void setParts(Parts part){
getPrimaryKey().setParts(part);
}
#Column(name = "cost")
public String getCost() {
return cost;
}
public void setCost(String cost) {
this.cost = cost;
}
}
import java.io.Serializable;
import javax.persistence.*;
#Embeddable
public class CatalogId implements Serializable{
private Suppliers suppliers;
private Parts parts;
#ManyToOne (cascade = CascadeType.ALL)
public Suppliers getSupplier() {
return suppliers;
}
public void setSupplier(Suppliers suppliers) {
this.suppliers = suppliers;
}
#ManyToOne(cascade = CascadeType.ALL)
public Parts getParts() {
return parts;
}
public void setParts(Parts parts) {
this.parts = parts;
}
}
import java.util.*;
import javax.persistence.*;
#Entity
#Table(name = "suppliers")
public class Suppliers {
private long sid;
private String sname;
private String address;
private Set<Catalog> catalogSet = new HashSet<Catalog>();
public Suppliers(String sname, String address) {
this.sname = sname;
this.address = address;
}
public Suppliers() {
}
#Id
#GeneratedValue
#Column(name = "sid")
public long getSid() {
return this.sid;
}
public void setSid(long sid) {
this.sid = sid;
}
#Column(name= "sname")
public String getSname() {
return this.sname;
}
public void setSname(String sname) {
this.sname = sname;
}
#Column(name = "address")
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
#OneToMany(mappedBy = "primaryKey.suppliers", cascade = CascadeType.ALL)
public Set<Catalog> getCatalogSet() {
return catalogSet;
}
public void setCatalogSet(Set<Catalog> catalogSet) {
this.catalogSet = catalogSet;
}
public void addRecipe(Catalog catalog){
this.catalogSet.add(catalog);
}
}
import java.util.*;
import javax.persistence.*;
#Entity
#Table(name = "parts")
public class Parts {
private long pid;
private String pname;
private String color;
private Set<Catalog> catalogSet = new HashSet<Catalog>();
public Parts(String pname, String color) {
super();
this.pname = pname;
this.color = color;
}
public Parts() {
super();
}
#Id
#GeneratedValue
#Column(name = "pid")
public long getPid() {
return pid;
}
public void setPid(long pid) {
this.pid = pid;
}
#Column(name = "pname")
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
#Column(name = "color")
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
#OneToMany(mappedBy = "primaryKey.parts", cascade = CascadeType.ALL)
public Set<Catalog> getCatalogSet() {
return this.catalogSet;
}
public void setCatalogSet(Set<Catalog> catalogSet) {
this.catalogSet = catalogSet;
}
public void addCatalog(Catalog catalog){
this.catalogSet.add(catalog);
}
}
This is my (unfinished query code):
import org.hibernate.*;
import org.hibernate.boot.*;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.swing.*;
public class HibernateHql
{
public static void main(String[] args)
{
HibernateSession hibernateSession = new HibernateSession();
SessionFactory sessionFactory;
Session session;
String option = "";
String instruction = "Enter a: Return distinct sids and snames of suppliers who supply a red part or a green part." + "\n" +
"Enter b: Return distinct pids, pnames, and the maximum cost of that part amoung all suppliers that offer the part and that maximum cost is less than 70." + "\n" +
"Enter c: Insert a new catalog row given the supplier id, the part id, and the cost fromthe user of your program." + "\n" +
"Enter d: Quit Program";
try
{
while(true)
{
option = JOptionPane.showInputDialog(instruction);
hibernateSession.setUp();
sessionFactory = hibernateSession.getSessionFactory();
session = sessionFactory.openSession();
session.beginTransaction();
if(option.equals("a"))
{
List results = session.createQuery("select distinct c from Parts p join p.catalogSet c where p.color = :color1 or p.color = :color2").setParameter("color1", "red").setParameter("color2", "green").getResultList();
String toShow = "These are suppliers who supply a red or green part:\n";
for(int i=0;i<results.size();i++)
{
Suppliers theSupplier = (Suppliers)((Catalog)results.get(i)).getSuppliers();
toShow += (i+1) + ") " + theSupplier.getSname() + "\n";
}
JOptionPane.showMessageDialog(null, toShow);
}
else if(option.equals("b"))
{
List results = session.createQuery("select max(r.cost)from Suppliers s inner join s.catalogSet r group by f").getResultList();
String toShow = "These are all parts:\n";
for(int i=0;i<results.size();i++)
{
Parts thePart = (Parts)((Catalog)results.get(i)).getParts();
String cost = ((Catalog)results.get(i)).getCost();
if(Integer.parseInt(cost) <= 70){
toShow += (i+1) + ") " + thePart.getPname() + " " + cost;
}
}
JOptionPane.showMessageDialog(null, toShow);
}
else if(option.equals("c"))
{
String allSuppliers = "SID" + "....." + "SNAME" + "\n";
List allS = session.createQuery("from Suppliers").getResultList();
for(int i=0;i<allS.size();i++)
{
Suppliers theSupplier = (Suppliers)allS.get(i);
allSuppliers += theSupplier.getSid() + "....." + theSupplier.getSname() + "\n";
}
JOptionPane.showMessageDialog(null, allSuppliers);
String supplierID = JOptionPane.showInputDialog("Enter Supplier ID: ");
String allParts = "PID" + "....." + "PNAME" + "\n";
List allP = session.createQuery("from Parts p where p.color = :color").setParameter("color", "blue").getResultList();
for(int i=0;i<allS.size();i++)
{
Parts theParts = (Parts)allP.get(i);
allParts += theParts.getPid() + "....." + theParts.getPname() + "\n";
}
JOptionPane.showMessageDialog(null, allParts);
String partsID = JOptionPane.showInputDialog("Enter Parts ID: ");
// List results = session.createQuery("select f1 from Food f1 where f1 not in (select distinct r.primaryKey.food from Ingredient i inner join i.recipeSet r where i.iname = :iname)").setParameter("iname", "Green Onion").getResultList();
// String toShow = "These foods don't have green onion:\n";
// for(int i=0;i<results.size();i++)
// {
// Food theFood = (Food)results.get(i);
// toShow += (i+1) + ") " + theFood.getFname() + "\n";
// }
// JOptionPane.showMessageDialog(null, toShow);
}
else
{
break;
}
session.getTransaction().commit();
session.close();
}
JOptionPane.showMessageDialog(null, "Good Bye");
}
catch(Exception e)
{
System.out.println("There is an error:");
System.out.println(e.toString());
}
}
}
Thank you in advance for your help!
In Suppliers class you have mapped the catalogSet as below:
#OneToMany(mappedBy = "primaryKey.suppliers", cascade = CascadeType.ALL)
public Set<Catalog> getCatalogSet() {
return catalogSet;
}
I do not find any field in Suppliers class called primaryKey. I think you should use sid here to map the relationship between catalogSet and Suppliers class.
Please let me know if I misunderstood your question.

JPA many-to-many saves duplicate entities

I have difficulties with JPA many-to-many unidirectional relationship. The problem is that duplicate Label entities are created in DB even if they are the same. For performance reason the #Id is a generated number and not Label.label. The connected problem is that findByLabel() does not find the two notes.
I read many articles and examples and I think I have similar code, but it doesn't work. Any help is appreciated.
I'm using Spring Boot, H2, Spring Data JPA. I am looking for non-XML, pure Java annotation solution.
Repository:
public interface NoteRepository extends CrudRepository<Note, Long> {
#Query("SELECT a from Note a where ?1 member of a.labels")
List<Note> findByLabel(Label label); }
Label:
#Entity
public class Label {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "label_id")
private Long labelId;
private String label;
protected Label() {
}
public Label(String label) {
this.label = label;
}
public Long getLabelId() {
return labelId;
}
public void setLabelId(Long labelId) {
this.labelId = labelId;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Label)) return false;
Label label1 = (Label) o;
return getLabel().equals(label1.getLabel());
}
#Override
public int hashCode() {
return Objects.hash(getLabel());
}
#Override
public String toString() {
return "Label{" +
"labelId=" + labelId +
", label='" + label + '\'' +
'}';
}
}
Note:
#Entity
public class Note {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "note_id")
private Long noteId;
private String note;
#ManyToMany(
fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
#JoinTable(
name = "Note_Label",
joinColumns = #JoinColumn(
name = "NoteId",
referencedColumnName = "note_id"),
inverseJoinColumns = #JoinColumn(
name = "LabelId",
referencedColumnName = "label_id"))
private Set<Label> labels;
protected Note() {
}
public Note(String note, Set<Label> labels) {
this.note = note;
this.labels = labels;
}
public Note(String note) {
this(note, null);
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Long getNoteId() {
return noteId;
}
public void setNoteId(Long noteId) {
this.noteId = noteId;
}
public Set<Label> getLabels() {
return labels;
}
public void setLabels(Set<Label> labels) {
this.labels = labels;
}
#Override
public String toString() {
return "Note{" +
"note='" + note + '\'' +
", labels='" + labels + '\'' +
'}';
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Note)) return false;
Note note1 = (Note) o;
if (!getNote().equals(note1.getNote())) return false;
return getLabels() != null ? getLabels().equals(note1.getLabels()) : note1.getLabels() == null;
}
#Override
public int hashCode() {
int result = getNote() != null ? getNote().hashCode() : 0;
result = 31 * result + (getLabels() != null ? getLabels().hashCode() : 0);
return result;
}
}
Test fails:
#SpringBootTest
#RunWith(SpringRunner.class)
public class NoteRepositoryTest {
#Autowired
private NoteRepository repository;
#Test
public void findByLabel() throws Exception {
String labelAString = "labelA";
Label labelA = new Label(labelAString);
Label labelA1 = new Label(labelAString);
Label labelB = new Label("labelB");
Label labelC = new Label("labelC");
Note note1 = new Note(
"note1", new HashSet<Label>(Arrays.asList(
labelA, labelB)));
Note note2 = new Note(
"note2", new HashSet<Label>(Arrays.asList(
labelA1, labelC)));
repository.deleteAll();
repository.save(note1);
repository.save(note2);
List<Note> actualNotes = repository.findByLabel(labelA);
System.out.println(actualNotes);
assertTrue(actualNotes.size() == 2);
assertTrue(actualNotes.containsAll(Arrays.asList(note1, note2)));
}
}
the right code:
#Test
public void saveAndGet() throws Exception {
String labelAString = "labelA";
Label labelA = new Label(labelAString);
Label labelA1 = new Label(labelAString);
Label labelB = new Label("labelB");
Label labelC = new Label("labelC");
repository.save(labelA);
System.out.println(labelA.getLabelId());
repository.save(labelB);
Iterable<Label> all = repository.findAll();
all.forEach(p ->{
System.out.println(p.getLabel());
System.out.println(p.getLabelId());
});
}

Hibernate #OneToMany fails with "collection is not associated with any session"

Here's the point: I want to load "DeliveryOrderEntity" (code below) from DB (MySQL). It has 1 foreign key with "one-to-many" relationship. It connects "BillsEntity" using billNumber. To make it clear - I have table ORDER with column BILL_NUMBER and table BILL with columns BILL_ID (primary key) and BILL_NUMBER (column, that connects BILL with ORDER).
Here is my code:
DeliveryOrderEntity.java:
#Entity
#Table(name = "DELIVERY_ORDER", schema = "", catalog = "kursach")
#NamedQueries(value = {
#NamedQuery(name = "findAllOrders", query = "from DeliveryOrderEntity"),
#NamedQuery(name = "getOrder", query = "from DeliveryOrderEntity where orderId=:orderId"),
#NamedQuery(name = "removeOrder", query = "delete from DeliveryOrderEntity where orderId=:orderId")
})
public class DeliveryOrderEntity implements Serializable{
private int orderId;
private Timestamp orderDate;
private String orderName;
private String orderTelephone;
private Integer billNumber;
private Integer regionId;
private List<BillEntity> listBill;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ORDER_ID")
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
#Basic
#Column(name = "ORDER_DATE")
public Timestamp getOrderDate() {
return orderDate;
}
public void setOrderDate(Timestamp orderDate) {
this.orderDate = orderDate;
}
#Basic
#Column(name = "ORDER_NAME")
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
#Basic
#Column(name = "ORDER_TELEPHONE")
public String getOrderTelephone() {
return orderTelephone;
}
public void setOrderTelephone(String orderTelephone) {
this.orderTelephone = orderTelephone;
}
#Basic
#Column(name = "BILL_NUMBER")
public Integer getBillNumber() {
return billNumber;
}
public void setBillNumber(Integer billNumber) {
this.billNumber = billNumber;
}
#Basic
#Column(name = "REGION_ID")
public Integer getRegionId() {
return regionId;
}
public void setRegionId(Integer regionNumber) {
this.regionId = regionNumber;
}
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
#Fetch(FetchMode.JOIN)
#JoinColumn(name = "BILL_NUMBER", referencedColumnName = "BILL_NUMBER", nullable = false, insertable = false, updatable = false)
public List<BillEntity> getListBill() {
return listBill;
}
public void setListBill(List<BillEntity> listBill) {
this.listBill = listBill;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DeliveryOrderEntity entity = (DeliveryOrderEntity) o;
if (orderId != entity.orderId) return false;
if (orderDate != null ? !orderDate.equals(entity.orderDate) : entity.orderDate != null) return false;
if (orderName != null ? !orderName.equals(entity.orderName) : entity.orderName != null) return false;
if (orderTelephone != null ? !orderTelephone.equals(entity.orderTelephone) : entity.orderTelephone != null)
return false;
if (billNumber != null ? !billNumber.equals(entity.billNumber) : entity.billNumber != null) return false;
return !(regionId != null ? !regionId.equals(entity.regionId) : entity.regionId != null);
}
#Override
public int hashCode() {
int result = orderId;
result = 31 * result + (orderDate != null ? orderDate.hashCode() : 0);
result = 31 * result + (orderName != null ? orderName.hashCode() : 0);
result = 31 * result + (orderTelephone != null ? orderTelephone.hashCode() : 0);
result = 31 * result + (billNumber != null ? billNumber.hashCode() : 0);
return result;
}
}
BillsEntity.java:
#Entity
#Table(name = "BILL")
#NamedQueries({
#NamedQuery(name = "findAllBills", query = "from BillEntity"),
#NamedQuery(name = "findAllBillIds", query = "select billNumber from BillEntity group by billNumber"),
#NamedQuery(name = "findAllBillsById", query = "from BillEntity where billNumber=:billNumber")
})
public class BillEntity implements Serializable {
private int billId;
private Integer billNumber;
private Integer goodCount;
private Integer goodId;
private Integer billStatus;
private GoodsEntity good;
#Id
#Column(name = "BILL_ID")
public int getBillId() {
return billId;
}
public void setBillId(int billId) {
this.billId = billId;
}
#Basic
#Column(name = "BILL_NUMBER", updatable = false, insertable = false)
public Integer getBillNumber() {
return billNumber;
}
public void setBillNumber(Integer billNumber) {
this.billNumber = billNumber;
}
#Basic
#Column(name = "GOOD_COUNT")
public Integer getGoodCount() {
return goodCount;
}
public void setGoodCount(Integer goodCount) {
this.goodCount = goodCount;
}
#Basic
#Column(name = "BILL_STATUS")
public Integer getBillStatus() {
return billStatus;
}
#Basic
#Column(name = "GOOD_ID")
public Integer getGoodId() {
return goodId;
}
public void setGoodId(Integer goodId) {
this.goodId = goodId;
}
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GOOD_ID", referencedColumnName = "GOOD_ID", nullable = false, insertable = false, updatable = false)
public GoodsEntity getGood() {
return good;
}
public void setGood(GoodsEntity good) {
this.good = good;
}
public void setBillStatus(Integer billStatus) {
this.billStatus = billStatus;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BillEntity that = (BillEntity) o;
if (billId != that.billId) return false;
if (billNumber != null ? !billNumber.equals(that.billNumber) : that.billNumber != null) return false;
if (goodCount != null ? !goodCount.equals(that.goodCount) : that.goodCount != null) return false;
if (goodId != null ? !goodId.equals(that.goodId) : that.goodId != null) return false;
return !(billStatus != null ? !billStatus.equals(that.billStatus) : that.billStatus != null);
}
#Override
public int hashCode() {
int result = billId;
result = 31 * result + (billNumber != null ? billNumber.hashCode() : 0);
result = 31 * result + (goodCount != null ? goodCount.hashCode() : 0);
result = 31 * result + (goodId != null ? goodId.hashCode() : 0);
result = 31 * result + (billStatus != null ? billStatus.hashCode() : 0);
return result;
}
#Override
public String toString() {
return "BillEntity{" +
"billId=" + billId +
", billNumber=" + billNumber +
", goodCount=" + goodCount +
", billStatus=" + billStatus +
", good=" + good +
'}';
}
}
As you can see, I have unidirectional OneToMany relationship. The problem is that when i have 2 rows in DELIVERY_ORDER table with the same BILL_NUMBER and I try to get list of orders - it fails with:
Caused by: org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:676)
at org.hibernate.engine.internal.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:1030)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:346)
at org.hibernate.loader.Loader.doList(Loader.java:2522)
at org.hibernate.loader.Loader.doList(Loader.java:2508)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2338)
at org.hibernate.loader.Loader.list(Loader.java:2333)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1269)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264)
Here is the code where i fetch the list:
public List<DeliveryOrderEntity> listOrders() {
List findAllOrders = new ArrayList();
EntityManager entityManager = transactionManager.getEntityManagerFactory().createEntityManager();
try {
entityManager.getTransaction().begin();
findAllOrders = entityManager.createNamedQuery("findAllOrders").getResultList();
} catch (Exception e) {
e.printStackTrace();
} finally {
entityManager.getTransaction().commit();
}
return findAllOrders;
}
Thank you in advance.

Column does not exist - Hibernate ManyToMany association class

I'm facing the following problem. Imagine this data model:
As you can see project_function entity is association many to many entity.
Here are my entity classes.
PeronalCard:
#Entity
#Table(name = "personal_card")
#XmlRootElement
public class PersonalCard implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_person")
private Integer idPerson;
/* SOME OTHER ATTRIBUTES */
#OneToMany(cascade = CascadeType.ALL, mappedBy = "projectFunctionPK.personalCard")
private Set<ProjectFunction> projectFunctionSet;
public PersonalCard() {
}
public Integer getIdPerson() {
return idPerson;
}
public void setIdPerson(Integer idPerson) {
this.idPerson = idPerson;
}
#XmlTransient
public Set<ProjectFunction> getProjectFunctionSet() {
return projectFunctionSet;
}
public void setProjectFunctionSet(Set<ProjectFunction> projectFunctionSet) {
this.projectFunctionSet = projectFunctionSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idPerson != null ? idPerson.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof PersonalCard)) {
return false;
}
PersonalCard other = (PersonalCard) object;
if ((this.idPerson == null && other.idPerson != null) || (this.idPerson != null && !this.idPerson.equals(other.idPerson))) {
return false;
}
return true;
}
}
Project:
#Entity
#Table(name = "project")
#XmlRootElement
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id_project")
private Integer idProject;
/* OTHER ATTRIBUTES*/
#OneToMany(cascade = CascadeType.ALL, mappedBy = "projectFunctionPK.project")
private Set<ProjectFunction> projectFunctionSet;
public Project() {
}
public Integer getIdProject() {
return idProject;
}
public void setIdProject(Integer idProject) {
this.idProject = idProject;
}
#XmlTransient
public Set<ProjectFunction> getProjectFunctionSet() {
return projectFunctionSet;
}
public void setProjectFunctionSet(Set<ProjectFunction> projectFunctionSet) {
this.projectFunctionSet = projectFunctionSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idProject != null ? idProject.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Project)) {
return false;
}
Project other = (Project) object;
if ((this.idProject == null && other.idProject != null) || (this.idProject != null && !this.idProject.equals(other.idProject))) {
return false;
}
return true;
}
}
ProjectFunction:
#Entity
#Table(name = "project_function")
#XmlRootElement
#AssociationOverrides({
#AssociationOverride(name = "projectFunctionPK.project",
joinColumns = #JoinColumn(name = "id_project", referencedColumnName = "id_project")),
#AssociationOverride(name = "projectFunctionPK.personalCard",
joinColumns = #JoinColumn(name = "id_person", referencedColumnName = "id_person")) })
public class ProjectFunction implements Serializable {
private static final long serialVersionUID = 1L;
protected ProjectFunctionPK projectFunctionPK;
private Date fromd;
private Date tod;
public ProjectFunction() {
this.projectFunctionPK = new ProjectFunctionPK();
}
#EmbeddedId
public ProjectFunctionPK getProjectFunctionPK() {
return projectFunctionPK;
}
public void setProjectFunctionPK(ProjectFunctionPK projectFunctionPK) {
this.projectFunctionPK = projectFunctionPK;
}
#Column(name = "fromd")
#Temporal(TemporalType.DATE)
public Date getFromd() {
return fromd;
}
public void setFromd(Date fromd) {
this.fromd = fromd;
}
#Column(name = "tod")
#Temporal(TemporalType.DATE)
public Date getTod() {
return tod;
}
public void setTod(Date tod) {
this.tod = tod;
}
#Transient
public Project getProject() {
return projectFunctionPK.getProject();
}
public void setProject(Project project) {
this.projectFunctionPK.setProject(project);
}
#Transient
public PersonalCard getPersonalCard() {
return this.projectFunctionPK.getPersonalCard();
}
public void setPersonalCard(PersonalCard personalCard) {
//this.personalCard = personalCard;
this.projectFunctionPK.setPersonalCard(personalCard);
}
#Override
public int hashCode() {
int hash = 0;
hash += (projectFunctionPK != null ? projectFunctionPK.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof ProjectFunction)) {
return false;
}
ProjectFunction other = (ProjectFunction) object;
if ((this.projectFunctionPK == null && other.projectFunctionPK != null) || (this.projectFunctionPK != null && !this.projectFunctionPK.equals(other.projectFunctionPK))) {
return false;
}
return true;
}
}
And finally my embedded Primary Key ProjectFunctionPK:
#Embeddable
public class ProjectFunctionPK implements Serializable {
#ManyToOne
private Project project;
#ManyToOne
private PersonalCard personalCard;
public ProjectFunctionPK() {
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public PersonalCard getPersonalCard() {
return personalCard;
}
public void setPersonalCard(PersonalCard personalCard) {
this.personalCard = personalCard;
}
#Override
public int hashCode() {
int hash = 3;
hash = 41 * hash + Objects.hashCode(this.project);
hash = 41 * hash + Objects.hashCode(this.personalCard);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ProjectFunctionPK other = (ProjectFunctionPK) obj;
if (!Objects.equals(this.project, other.project)) {
return false;
}
if (!Objects.equals(this.personalCard, other.personalCard)) {
return false;
}
return true;
}
}
First I save the Project. It works fine. Then i want to connect it using project_function - so I create project_function set them existing project and personal_card and after trying to persist I get following error:
Caused by: org.postgresql.util.PSQLException: ERROR: column projectfun0_.personalcard does not exist
Position: 8
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:304)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
... 119 more
So apparently Hibernate does not know projectfun0_.personalcard . But I dont know why. Do you see any error in the entity classes? Or could the error possibly be somewhere else ?
Thank you very much for all your answers :)
EmbeddedId documentation
Relationship mappings defined within an embedded id class are not supported.
So, ProjectFunctionPK should contain only basic mappings, and entity mappings should be done in the entity itself. Here are some related posts
https://stackoverflow.com/a/9760808/4074715
https://stackoverflow.com/a/4692144/4074715

How to set and get values for Composite primary keys and other fields in jpa?

This is my Entity class
#EmbeddedId
private AuthorWorkPKEmbedded embeddedId;
#Column(name = "ColumnA")
private String ColumnA;
public AuthorWorkPKEmbedded getEmbeddedId() {
return embeddedId;
}
public void setEmbeddedId(AuthorWorkPKEmbedded embeddedId) {
this.embeddedId = embeddedId;
}
public String getColumnA() {
return ColumnA;
}
public void setColumnA(String ColumnA) {
this.ColumnA = ColumnA;
}
public AuthorWorkEmbedded() {
}
public AuthorWorkEmbedded(BigInteger bookId,BigInteger authorId) {
this.embeddedId = new AuthorWorkPKEmbedded(bookId, authorId);
}
This is my Embeddable class
#Embeddable
#Column(name = "bookId", nullable = false)
private BigInteger bookId;
#Column(name = "authorId", nullable = false)
private BigInteger authorId;
public AuthorWorkPKEmbedded() {
}
public AuthorWorkPKEmbedded(BigInteger bookId, BigInteger authorId) {
this.bookId = bookId;
this.authorId = authorId;
}
public BigInteger getBookId() {
return bookId;
}
public void setBookId(BigInteger bookId) {
this.bookId = bookId;
}
public BigInteger getAuthorId() {
return authorId;
}
public void setAuthorId(BigInteger authorId) {
this.authorId = authorId;
}
#Override
public int hashCode() {
return bookId.hashCode() + authorId.hashCode();
}
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof AuthorWorkPKEmbedded)) {
return false;
}
if (obj == null) {
return false;
}
AuthorWorkEmbedded pk=(AuthorWorkEmbedded) obj;
return (((bookId==((AuthorWorkPKEmbedded)obj).getBookId()))
&&((authorId==((AuthorWorkPKEmbedded)obj).getAuthorId())));
}
This is my main class
how set the composite values and why cant we use generatedvalue for autoincrement purpose and how to retrieve the values from the the database and one more thing where to declare other fields in Entity class or embeddable class and if not how to set and get the values from these 2 classes(entity and embeddable)
EntityTransaction entr = em.getTransaction();
entr.begin();
AuthorWorkPKEmbedded author = new AuthorWorkPKEmbedded();
author.setBookId(BigInteger.ONE);
author.setAuthorId(BigInteger.ONE);
AuthorWorkEmbedded a1=new AuthorWorkEmbedded();
a1.setEmbeddedId(author);
a1.setColumnA("Pirates of carrabian");
boolean successful = false;
try {
em.persist(author);
successful = true;
} finally {
if (successful) {
entr.commit();
} else {
entr.rollback();
}
}
Query query = em.createNamedQuery("AuthorWork.findAll");
List authorList = query.getResultList();
Iterator authorIterator = authorList.iterator();
while (authorIterator.hasNext()) {
author = (AuthorWorkPKEmbedded) authorIterator.next();
System.out.println("Book Id " + author.getBookId() + " " + "Author" + author.getAuthorId() + "");
System.out.println();
}
Use getters and setters for embeddedId .
Query query = em.createNamedQuery("AuthorWork.findAll");
List authorList = query.getResultList();
Iterator authorIterator = authorList.iterator();
while (authorIterator.hasNext()) {
author = (AuthorWorkEmbedded) authorIterator.next();
System.out.println("Book Id " + author.setEmbeddedId().getBookId() + " " + "Author" + author.getEmbeddedId().getAuthorId() + "");
System.out.println(""+author.getColumnA());
}

Categories