Spring Rest `#Controller` wiered behaviour - java

I am trying hands on Spring Rest service via #Controller. But i came across situation where one method call is responding with valid data and other filtered method call returning incorrect response. Here is my controller
#Controller
#RequestMapping("/company")
public class CompanyDetailsController {
#Autowired
private CompanyServices companyServices;
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody List<CompanyDetails> getCompanyDetails() {
return companyServices.getCompanyDetails();
}
#RequestMapping(value = "/{companyShortCode}", method = RequestMethod.GET)
public #ResponseBody CompanyDetails getCompanyDetails(#PathVariable("companyShortCode") String companyShortCode) {
System.out.println("companyShortCode = "+companyShortCode);
CompanyDetails companyDetails = companyServices.getCompanyDetails(companyShortCode);
/*CompanyDetails companyDetails = new CompanyDetails();
companyDetails.setCompanyCode("abc");
companyDetails.setCompanyEmail("abc#123.com");
companyDetails.setCompanyPhone(92349234);
companyDetails.setWebSite("abc.abc.com");
System.out.println("companyDetails = "+companyDetails);*/
return companyDetails;
}
}
CompanyDetails
#Entity
#Table(name = "company_details")
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class CompanyDetails implements Serializable {
private static final long serialVersionUID = 8713608417980657723L;
#Id
#Column(name="COMPANY_CODE", nullable = false, updatable = false)
private String companyCode = null;
#Column(name = "COMPANY_NAME", nullable = false, updatable = true)
private String companyName = null;
#Column(name = "COMPANY_PHONE", nullable = true, updatable = true)
private long companyPhone = 0;
#Column(name = "COMPANY_EMAIL", nullable = true, updatable = true)
private String companyEmail = null;
#Column(name = "COMPANY_WEBSITE", nullable = true, updatable = true)
private String webSite = null;
public String getCompanyCode() {
return companyCode;
}
public void setCompanyCode(String companyCode) {
this.companyCode = companyCode;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public long getCompanyPhone() {
return companyPhone;
}
public void setCompanyPhone(long companyPhone) {
this.companyPhone = companyPhone;
}
public String getCompanyEmail() {
return companyEmail;
}
public void setCompanyEmail(String companyEmail) {
this.companyEmail = companyEmail;
}
public String getWebSite() {
return webSite;
}
public void setWebSite(String webSite) {
this.webSite = webSite;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((companyCode == null) ? 0 : companyCode.hashCode());
result = prime * result
+ ((companyName == null) ? 0 : companyName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CompanyDetails other = (CompanyDetails) obj;
if (companyCode == null) {
if (other.companyCode != null)
return false;
} else if (!companyCode.equals(other.companyCode))
return false;
if (companyName == null) {
if (other.companyName != null)
return false;
} else if (!companyName.equals(other.companyName))
return false;
return true;
}
#Override
public String toString() {
return "CompanyDetails [companyCode=" + companyCode + ", companyName="
+ companyName + ", companyPhone=" + companyPhone
+ ", companyEmail=" + companyEmail + ", webSite=" + webSite
+ "]";
}
}
Repository
#Repository
public class DetailsDaoImpl implements DetailsDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
#Transactional(readOnly = true)
public List<CompanyDetails> getCompanyDetails() {
List<CompanyDetails> details = (List<CompanyDetails>) sessionFactory.getCurrentSession().createCriteria(CompanyDetails.class).list();
return details;
}
#Override
#Transactional(readOnly = true)
public CompanyDetails getCompanyDetails(String companyShortCode) {
System.out.println("companyShortCode = "+companyShortCode);
CompanyDetails details = (CompanyDetails) sessionFactory.getCurrentSession().load(CompanyDetails.class, companyShortCode);
System.out.println("details = "+details);
return details;
}
}
Service
public class CompanyServicesImpl implements CompanyServices {
#Autowired
DetailsDao detailsDao;
#Override
public List<CompanyDetails> getCompanyDetails() {
return detailsDao.getCompanyDetails();
}
#Override
public CompanyDetails getCompanyDetails(String companyShortCode) {
System.out.println("companyShortCode = "+companyShortCode);
return detailsDao.getCompanyDetails(companyShortCode);
}
}
If I call List<CompanyDetails> getCompanyDetails(), It return -
[
{
"companyCode": "ABCD",
"companyName": "Test Company",
"companyPhone": 11226123456,
"companyEmail": "abc#abcd.com",
"webSite": "www.abc.com"
},
{
"companyCode": "XYZA",
"companyName": "XYZA Company",
"companyPhone": 1122000000,
"companyEmail": "abc#XYZA.com",
"webSite": "www.XYZA.com"
}
]
But when i call - Public #ResponseBody CompanyDetails getCompanyDetails(#PathVariable("companyShortCode") String companyShortCode) {,
It return -
{"companyPhone": 0}
I tried with dummy Object and it makes it to Json. Tried Creating normal bean and not #Entity and used BeanUtils to copy properties and responding the correct Json. Anyone Know why this is happening?
Updated
before sending response, it is printing as CompanyDetails [companyCode=ABCD, companyName=Test Company, companyPhone=9823611147, companyEmail=abc#abcd.com, webSite=www.abc.com]

In your public CompanyDetails getCompanyDetails(String companyShortCode) method when you are retrieving CompanyDetails object using its Primary Key companyShortCode you are using load method.
load method return a proxy object in which only Primary Key attribute is set and all other attributes are not set. Your session object will send query for retrieving the actual object only when you call any one of getter method for a attribute like details.getCompanyEmail().
So for avoiding that you can call get method. See below code snippet:
#Override
#Transactional(readOnly = true)
public CompanyDetails getCompanyDetails(String companyShortCode) {
System.out.println("companyShortCode = "+companyShortCode);
CompanyDetails details = (CompanyDetails) sessionFactory.getCurrentSession().get(CompanyDetails.class, companyShortCode);
System.out.println("details = "+details);
return details;
}
}
If you want to go for load method then use below code snippet:
#Override
#Transactional(readOnly = true)
public CompanyDetails getCompanyDetails(String companyShortCode) {
System.out.println("companyShortCode = "+companyShortCode);
CompanyDetails details = (CompanyDetails) sessionFactory.getCurrentSession().load(CompanyDetails.class, companyShortCode);
details.getCompanyName(); //after this all attribute of CompanyDetails object will be set
System.out.println("details = "+details);
return details;
}
}
For more reference see this
Hope it helps.

First of all the code is not completely posted, And I am not clear wi ththe response of the second call. The problem might be in the companyservices where you might be creating new object rather than fetching from JPA or from its underlying platform. Another cause might be the JPA configuration.

Related

Mapping issue on Hibernate

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.

Spring + hibernate : Expected type: java.util.SortedSet, actual value: org.hibernate.collection.internal.PersistentSet

I have a Client.class which has a OneToMany relation with Posto.class.
#Entity
#Table(name = "client", catalog = "SMARTPARK")
public class Client implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int idClient;
private String nomeClient;
private int numPosti;
private int numLuci;
private String currentIp;
private boolean online;
private String prop;
private SortedSet<Posto> posti = new TreeSet<>();
private SortedSet<Luce> luci = new TreeSet<>();
public Client() {
}
public Client(int idClient, String nomeClient, int numPosti, int numLuci,
String currentIp, boolean online, String prop,
SortedSet<Posto> posti, SortedSet<Luce> luci) {
this.idClient = idClient;
this.nomeClient = nomeClient;
this.numPosti = numPosti;
this.numLuci = numLuci;
this.currentIp = currentIp;
this.prop = prop;
this.online = online;
this.posti = posti;
this.luci = luci;
}
#Id
#Column(name = "id_client", unique = true, nullable = false)
public int getIdClient() {
return this.idClient;
}
public void setIdClient(int idClient) {
this.idClient = idClient;
}
#Column(name = "nome_client", nullable = false, length = 65535)
public String getNomeClient() {
return this.nomeClient;
}
public void setNomeClient(String nomeClient) {
this.nomeClient = nomeClient;
}
#Transient
public int getNumPosti() {
return this.numPosti;
}
public void setNumPosti(int numPosti) {
this.numPosti = numPosti;
}
#Transient
public int getNumLuci() {
return this.numLuci;
}
public void setNumLuci(int numLuci) {
this.numLuci = numLuci;
}
#Column(name = "client_ip", nullable=true)
public String getCurrentIp() {
return currentIp;
}
public void setCurrentIp(String currentIp) {
this.currentIp = currentIp;
}
#Column(name="online")
public boolean isOnline() {
return online;
}
public void setOnline(boolean online) {
this.online = online;
}
#Column(name="prop")
public String getProp() {
return prop;
}
public void setProp(String prop) {
this.prop = prop;
}
#OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy = "client", orphanRemoval=true)
#OrderBy("numeroPosto ASC")
public Set<Posto> getPosti() {
return posti;
}
public void setPosti(SortedSet<Posto> posti) {
this.posti = posti;
}
#OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy = "client", orphanRemoval=true)
#OrderBy("numeroLuce ASC")
public SortedSet<Luce> getLuci() {
return luci;
}
public void setLuci(SortedSet<Luce> luci) {
this.luci = luci;
}
This was made because a use the Set in a responseEntity Controller and I need to preserve the order of how postiis displayed in the Json output.
So in Posto.class I implemented Comparable interface, overrding the compareTo method
#Override
public int compareTo(Posto o) {
if(this.numeroPosto == o.numeroPosto){
return 0;
} else {
return this.numeroPosto > o.numeroPosto ? 1 : -1;
}
Now, when calling my controller, i got this error from Hibernate:
2016-03-30 16:18:07.486 ERROR [http-nio-8080-exec-6]: HHH000123: IllegalArgumentException in class: it.besmart.models.Client, setter method of property: posti
2016-03-30 16:18:07.486 ERROR [http-nio-8080-exec-6]: HHH000091: Expected type: java.util.SortedSet, actual value: org.hibernate.collection.internal.PersistentSet
How can i solve it? Hibernate changes my SortedSet in a PersistentSet, do I have to use this one to set my posti with the order i want?
The problem is you defined your posti and Luci as concrete SortSet. Hibernate PersistentSet implements generic Set interface. All you need to do is changing SortSet to generic Set and modify getters, setters accordingly.
private Set<Posto> posti;
private Set<Luce> luci;

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

JPA not merging neither flushing my entity

I'm facing a trouble where I've my transactions controlled by Spring Tx and when I do a merge and after flush, my implementation does not print the command neither the Spring Tx commit them.
Follows my code:
#Named
#Transactional(propagation = Propagation.MANDATORY, readOnly = false)
class AverbacaoDAOImpl extends AbstractDAOImpl<Averbacao, Long> implements AverbacaoDAO{
private List<Averbacao> atualizarAverbacoes(final List<Averbacao> averbacoes, final EtapaAverbacao etapa) {
int counter = 0;
for(Averbacao averbacao : averbacoes) {
averbacao.setEtapa(etapa);
atualizar(averbacao);
counter += 1;
}
entityManager.flush();
LOGGER.debug("Atualizado {} averbacoes para a etapa {}", counter, etapa);
return averbacoes;
}
}
private atualizar(Averbacao averbacao) {
entityManager.merge(averbacao);
}
Every objects in the list are managed by JPA (or I think that they're)
Follows logs:
Spring Transaction/Hibernate:
08:37:06,102 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Processing flush-time cascades
08:37:07,576 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Dirty checking collections
08:37:08,703 DEBUG [BilhetagemProcessManagerExecutor-1hread] [Collections] Collection found: [br.com.company.bilhetagem.brms.model.Proposta.propostaTaxaAplicaveis#35340], was: [br.com.company.bilhetagem.brms.model.Proposta.propostaTaxaAplicaveis#35340] (initialized)
08:37:08,706 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Flushed: 0 insertions, 0 updates, 0 deletions to 26047 objects
08:37:08,707 DEBUG [BilhetagemProcessManagerExecutor-1hread] [AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
08:37:08,707 DEBUG [BilhetagemProcessManagerExecutor-1hread] [EntityPrinter] Listing entities:
08:37:08,707 DEBUG [BilhetagemProcessManagerExecutor-1hread] [EntityPrinter] br.com.company.bilhetagem.brms.model.tarifas.TipoTarifaPercentual{percentualMultiplicador=1.0, tipo=OCD}
08:37:08,713 DEBUG [BilhetagemProcessManagerExecutor-1hread] [EntityPrinter] More......
Averbacao
#Entity
#Table(name = "TBIL_RELAC_AVERB_PROPT", schema = "BILHET")
#SecondaryTable(name = "TBIL_AVERBACAO", schema = "BILHET", pkJoinColumns = { #PrimaryKeyJoinColumn(name = "SEQ_NUMER_AVB") })
public final class Averbacao implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3229114271975034004L;
#Id
#Column(name = "SEQ_NUMER_AVB")
private long numeroAverbacao;
#ManyToOne(optional = false, targetEntity = Proposta.class)
#JoinColumn(name = "SEQ_NUMER_PRS", nullable = false)
private Proposta proposta;
#Column(name = "VLR_IS", scale = 15, precision = 2, nullable = true)
private Double valorIS;
#ManyToOne(optional = false)
#JoinColumn(name = "CTL_LOCAL_ORI", nullable = false, table = "TBIL_AVERBACAO")
private Localidade origem;
#ManyToOne(optional = false)
#JoinColumn(name = "CTL_LOCAL_DES", nullable = false, table = "TBIL_AVERBACAO")
private Localidade destino;
#ManyToOne(optional = true)
#JoinColumn(name = "CTL_LOCAL_FIM", nullable = true, table = "TBIL_AVERBACAO")
private Localidade destinoFinal;
#Column(name = "DHR_EMBAR", nullable = false, table = "TBIL_AVERBACAO")
#Temporal(TemporalType.DATE)
private Date dataEmbarque;
#Column(name = "IDT_CARGA_DSC", nullable = false, table = "TBIL_AVERBACAO")
private char tipoCargaDescarga;
#Column(name = "IDT_VEICU", nullable = false, table = "TBIL_AVERBACAO")
private String tipoVeiculo;
#Column(name = "STA_AVARI", nullable = false, table = "TBIL_AVERBACAO")
private char indicadorAvaria;
#Column(name = "STA_FLUVI", nullable = false, table = "TBIL_AVERBACAO")
private char indicadorTrechoFluvial;
#Column(name = "NUM_ETAPA_AVB", nullable = false, table = "TBIL_AVERBACAO")
#Type(type = "br.com.company.bilhetagem.brms.dao.jpa.types.EtapaAverbacaoUserType")
private EtapaAverbacao etapa;
public Averbacao() {
}
public Averbacao(final Proposta proposta) {
this.proposta = proposta;
}
#Transient
public AverbacaoPropostaKey getAverbacaoPropostaKey() {
final long numeroProposta =
this.proposta == null ? 0 : this.proposta.getNumeroProposta();
return new AverbacaoPropostaKey(this.numeroAverbacao, numeroProposta);
}
public Date getDataEmbarque() {
return new DateTime(dataEmbarque).toDate();
}
public Localidade getDestino() {
return destino;
}
public long getNumeroAverbacao() {
return numeroAverbacao;
}
public Localidade getOrigem() {
return origem;
}
public Proposta getProposta() {
return proposta;
}
public Double getValorIS() {
return valorIS;
}
public char getTipoCargaDescarga() {
return tipoCargaDescarga;
}
public String getTipoVeiculo() {
return tipoVeiculo;
}
public char getIndicadorAvaria() {
return indicadorAvaria;
}
public char getIndicadorTrechoFluvial() {
return indicadorTrechoFluvial;
}
public Localidade getDestinoFinal() {
return destinoFinal;
}
public final EtapaAverbacao getEtapa() {
return etapa;
}
public final void setEtapa(EtapaAverbacao etapa) {
this.etapa = etapa;
}
#Override
public String toString() {
return toStringHelper(this).addValue(this.numeroAverbacao)
.add("Proposta", this.proposta).add("Origem", this.origem)
.add("Destino", this.destino).addValue(this.dataEmbarque)
.addValue(this.valorIS).toString();
}
#Override
public int hashCode() {
return Objects.hashCode(this.dataEmbarque, this.destino,
this.numeroAverbacao, this.origem, this.proposta, this.valorIS,
this.tipoCargaDescarga, this.indicadorAvaria,
this.indicadorTrechoFluvial, this.destinoFinal);
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
final Averbacao that = (Averbacao) obj;
return equal(this.numeroAverbacao, that.getNumeroAverbacao())
&& equal(this.destino, that.getDestino())
&& equal(this.origem, that.getOrigem())
&& equal(this.proposta, that.getProposta());
}
}
EtapaAverbacao
public enum EtapaAverbacao implements Serializable, PersistentEnum {
NAO_PROCESSADO(1),
PROCESSANDO(2),
PROCESSADO(3);
private int id;
private EtapaAverbacao(final int id) {
this.id = id;
}
#Override
public int getId() {
return this.id;
}
}
public abstract class AbstractPersistentEnumUserType implements UserType {
public AbstractPersistentEnumUserType() {
}
public static List<Integer> toIdList(final List<? extends PersistentEnum> enumList) {
final List<Integer> ids = new ArrayList<Integer>();
if(enumList == null) {
return ids;
}
for(PersistentEnum e : enumList) {
ids.add(e.getId());
}
return ids;
}
public static List<Integer> toIdList(final PersistentEnum[] enumList) {
return toIdList(Arrays.asList(enumList));
}
#Override
public final int[] sqlTypes() {
return new int[] { Types.INTEGER };
}
#Override
public abstract Class<T> returnedClass();
#Override
public final boolean equals(Object obj1, Object obj2) {
if(obj1 == null) {
return false;
}
return obj1.equals(obj2);
}
#Override
public final int hashCode(Object obj) {
return obj == null ? 0 : obj.hashCode();
}
#Override
public final Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException {
if (rs.wasNull()) {
return null;
}
for (PersistentEnum value : returnedClass().getEnumConstants()) {
final int id = rs.getInt(names[0]);
if (id == value.getId()) {
return value;
}
}
throw new IllegalStateException("Unknown " + returnedClass().getSimpleName() + " id");
}
#Override
public final void nullSafeSet(PreparedStatement stmt, Object value, int index, SessionImplementor session) throws SQLException {
if (value == null) {
stmt.setNull(index, Types.INTEGER);
} else {
stmt.setInt(index, ((PersistentEnum) value).getId());
}
}
#Override
public final Object deepCopy(Object value) {
return value;
}
#Override
public final boolean isMutable() {
return false;
}
#Override
public final Serializable disassemble(Object value) {
return (Serializable) value;
}
#Override
public final Object assemble(Serializable cached, Object owner) {
return cached;
}
#Override
public final Object replace(Object original, Object target, Object owner) {
return original;
}
}
public class EtapaAverbacaoUserType extends
AbstractPersistentEnumUserType<EtapaAverbacao> {
#Override
public Class<EtapaAverbacao> returnedClass() {
return EtapaAverbacao.class;
}
}
After much effort I discovered with my team that the objects returned from query they were fetched as read only.
So, we get out the hint READ_ONLY in the query and now the objects can be updated

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