Java Hibernate - IllegalArgumentException - java

I have these 2 classes - Letadlo and Letiste (Plane and (Home)Airport). While saving data to DB, using java and hibernate , I'm getting this exception:
16285 [Thread-2] ERROR org.hibernate.property.BasicPropertyAccessor - IllegalArgumentException in class: mapy.Letiste, getter method of property: id
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of mapy.Letiste.id
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:198)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:227)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3876)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3584)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:203)
at org.hibernate.engine.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:159)
at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:91)
at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:69)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:310)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
at logika.UkladaniDoDtb.run(UkladaniDoDtb.java:34)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:172)
... 19 more
Saving part:
HibernateFactory.buildSessionFactory();
Session session = HibernateFactory.openSession();
session.beginTransaction().begin();
for(Object o: DocasneUloziste.objektyKeSmazani){
session.delete(o);
}
for (Linka l : DocasneUloziste.linky) {
session.saveOrUpdate(l);
}
for (Letadlo l : DocasneUloziste.letadla) { //this is 34 line
session.saveOrUpdate(l);
}
for (Letiste d : DocasneUloziste.seznamLetist) {
session.saveOrUpdate(d);
}
session.getTransaction().commit();
session.close();
xml of Letadlo:
<class name="mapy.Letiste">
<meta attribute="class-description">Tato trida obsahuje info o domovskem letisti</meta>
<id name="id" type="long" column="LETISTE_ID">
<generator class="native" />
</id>
<property name="kodLetiste" type="string" not-null="true" length="3" column="KOD_LETISTE"/>
<property name="mesto" type="string" not-null="true" length="35" column="MESTO" />
<set name="obsluhaLetadel" cascade="all">
<key column="LETISTE_ID" />
<one-to-many class="mapy.Letadlo" />
</set>
</class>
xml of Letiste:
<class name="mapy.Letiste">
<meta attribute="class-description">Tato trida obsahuje info o domovskem letisti</meta>
<id name="id" type="long" column="LETISTE_ID">
<generator class="native" />
</id>
<property name="kodLetiste" type="string" not-null="true" length="3" column="KOD_LETISTE"/>
<property name="mesto" type="string" not-null="true" length="35" column="MESTO" />
<set name="obsluhaLetadel" cascade="all">
<key column="LETISTE_ID" />
<one-to-many class="mapy.Letadlo" />
</set>
</class>
Class of letadlo contains all variables with getter and setters I had in XML and constructor with no parameter.
Thanks for any suggestion!
EDIT: Letiste Class
public class Letiste {
private Long id;
private String kodLetiste;
private String mesto;
private Set<Letadlo> obsluhaLetadel = new HashSet<Letadlo>();
public Letiste() {
}
public Letiste(String kodLetiste, String mesto) {
this.kodLetiste = kodLetiste;
this.mesto = mesto;
}
public String getKodLetiste() {
return kodLetiste;
}
public void setKodLetiste(String kodLetiste) {
this.kodLetiste = kodLetiste;
}
public String getMesto() {
return mesto;
}
public void setMesto(String mesto) {
this.mesto = mesto;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Letiste other = (Letiste) obj;
if ((this.kodLetiste == null) ? (other.kodLetiste != null) : !this.kodLetiste.equals(other.kodLetiste)) {
return false;
}
if ((this.mesto == null) ? (other.mesto != null) : !this.mesto.equals(other.mesto)) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 7;
hash = 13 * hash + (this.kodLetiste != null ? this.kodLetiste.hashCode() : 0);
hash = 13 * hash + (this.mesto != null ? this.mesto.hashCode() : 0);
return hash;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<Letadlo> getObsluhaLetadel() {
return obsluhaLetadel;
}
public void setObsluhaLetadel(Set<Letadlo> obsluhaLetadel) {
this.obsluhaLetadel = obsluhaLetadel;
}
EDIT: Letadlo Class
public class Letadlo {
private Long id;
private String kodLetadla;
private String kapacita;
private Integer dolet;
private Set<Linka> seznamLinek = new HashSet<Linka>();
private String letiste;
public Letadlo() {
}
public Letadlo(String kodLetadla, String kapacita , Integer dolet, String letiste) {
this.kodLetadla = kodLetadla;
this.kapacita = kapacita;
this.dolet = dolet;
this.letiste = letiste;
}
/**
* #return the kodLetadla
*/
public String getKodLetadla() {
return kodLetadla;
}
/**
* #param kodLetadla the kodLetadla to set
*/
public void setKodLetadla(String kodLetadla) {
this.kodLetadla = kodLetadla;
}
/**
* #return the kapacita
*/
public String getKapacita() {
return kapacita;
}
/**
* #param kapacita the kapacita to set
*/
public void setKapacita(String kapacita) {
this.kapacita = kapacita;
}
/**
* #return the dolet
*/
public Integer getDolet() {
return dolet;
}
/**
* #param dolet the dolet to set
*/
public void setDolet(Integer dolet) {
this.dolet = dolet;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Letadlo other = (Letadlo) obj;
if (this.kodLetadla != other.kodLetadla && (this.kodLetadla == null || !this.kodLetadla.equals(other.kodLetadla))) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + (this.kodLetadla != null ? this.kodLetadla.hashCode() : 0);
hash = 79 * hash + (this.kapacita != null ? this.kapacita.hashCode() : 0);
hash = 79 * hash + (this.dolet != null ? this.dolet.hashCode() : 0);
return hash;
}
/**
* #return the id
*/
public Long getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* #return the seznamLinek
*/
public Set<Linka> getSeznamLinek() {
return seznamLinek;
}
/**
* #param seznamLinek the seznamLinek to set
*/
public void setSeznamLinek(Set<Linka> seznamLinek) {
this.seznamLinek = seznamLinek;
}
/**
* #return the letiste
*/
public String getLetiste() {
return letiste;
}
/**
* #param letiste the letiste to set
*/
public void setLetiste(String letiste) {
this.letiste = letiste;
}

Related

"java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name", although attribute is set

Hibernate 5.6 with Spring 5.3 here.
When creating predicates to fetch data from a table with this code:
CriteriaBuilder cb = this.getSession().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(aliasToBeanClass);
Root root = cq.from(aliasToBeanClass); // aliasToBeanClass is set to UmsUserRoleVOImpl
predicates.add(cb.equal(root.get(key), value)); // key is set to "userName" - this line is causing the exception
I get this error:
java.lang.IllegalArgumentException: Unable to locate Attribute with
the the given name [userName] on this ManagedType
[com.myapp.ums.business.impl.UmsUserRoleVOImpl]
But the attribute userName is included in my VO, as well as a public setter and it's mapped in my .hbm.xml file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.myapp.ums.business.impl.UmsUserRoleVOImpl" table="ums_t_user_role"
proxy="com.myapp.ums.common.business.UmsUserRoleVO">
<composite-id>
<key-property name="userName" type="java.lang.String" column="fk_user_id"/>
<key-property name="roleName" type="java.lang.String" column="fk_role_id"/>
</composite-id>
</class>
</hibernate-mapping>
This is my VO:
public class UmsUserRoleVOImpl extends AbstractBasePropertiesImpl implements UmsUserRoleVO {
private static final long serialVersionUID = 2393634151578825216L;
private String roleName;
private String userName;
private List<PmPropertyVO> properties;
public UmsUserRoleVOImpl() {
}
#Get(AbstractBaseProperties.ROWGUID)
#Override
public Long getRowguid() {
return super.getRowguid();
}
#Set(AbstractBaseProperties.ROWGUID)
#Override
public void setRowguid(final Long rowguid) {
super.setRowguid(rowguid);
}
#Get(UmsUserRoleVO.ROLE_NAME)
public String getRoleName() {
return roleName;
}
#Set(UmsUserRoleVO.ROLE_NAME)
public void setRoleName(String roleName) {
this.roleName = roleName;
}
#GetCollection(value = UmsUserRoleVO.PROPERTIES, defaultObject = "com.myapp.pm.business.impl.PmPropertyVOImpl")
public List<PmPropertyVO> getProperties() {
return properties;
}
#SetCollection(value = UmsUserRoleVO.PROPERTIES, defaultObject = "com.myapp.pm.business.impl.PmPropertyVOImpl")
public void setProperties(List<PmPropertyVO> properties) {
this.properties = properties;
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof UmsUserRoleVOImpl)) {
return false;
}
UmsUserRoleVOImpl user = (UmsUserRoleVOImpl) o;
if (!(roleName.equals(user.getRoleName()))) {
return false;
}
return userName.equals(user.getUserName());
}
public int hashCode() {
int result = 17;
result = 29 * result + (roleName != null ? roleName.hashCode() : 0);
result = 29 * result + (userName != null ? userName.hashCode() : 0);
return result;
}
public String toString() {
return roleName + " " + userName;
}
#Get(UmsUserRoleVO.USER_NAME)
public String getUserName() {
return this.userName;
}
#Set(UmsUserRoleVO.USER_NAME)
public void setUserName(String userName) {
this.userName = userName;
}
There seems to be something wrong with the mapping, because Hibernate does not find any attribute of the UmsUserRoleVOImpl:
Any idea what could be causing this error?

Configuring JPA to handle HIBERNATE composite-id and key-property

I am trying to find the correct way to convert the below (Hibernate) XML to JPA annotations:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<class name="TesTEntry" table="RAW_SCORE">
<composite-id mapped="false" unsaved-value="undefined">
<key-property column="SSN" name="ssn" type="string"/>
<key-property column="SUB_TEST_CD" name="subTestCd" type="string"/>
</composite-id>
<property column="TEST_QY" generated="never" lazy="false"
name="testQy" type="java.lang.Short"/>
<property column="SYS_REC" generated="never" lazy="false"
name="sysRec" type="java.util.Date"/>
<property column="SYS_ID" generated="never" lazy="false"
name="sysId" type="java.lang.String"/>
</class>
Since I have two <key-property> I am not sure if I use #Id, or #EmbeddedId
Since I have two I am not sure if I use #Id, or #EmbeddedId
You mean probably IdClass. And it doesn't matter which one you use.
Let us say, you want to use #IdClass:
Define a class for your ID.
Implement equals and hashCode methods
Implement public default constructor
Implement the Serializable interface
Here is an example implementation (equals & hashCode are generated from IDE):
public class TestEntityPK implements Serializable {
private static final long serialVersionUID = -3424067518791080014L;
private String ssn;
private String subTestCd;
public TestEntityPK() { // }
public TestEntityPK(String ssn, String subTestCd) {
this.ssn = ssn;
this.subTestCd;
}
public String getSsn() {
return ssn;
}
public String getSubTestCd() {
return subTestCd;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ssn == null) ? 0 : ssn.hashCode());
result = prime * result
+ ((subTestCd == null) ? 0 : subTestCd.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;
TestEntityPK other = (TestEntityPK) obj;
if (ssn == null) {
if (other.ssn != null)
return false;
} else if (!ssn.equals(other.ssn))
return false;
if (subTestCd == null) {
if (other.subTestCd != null)
return false;
} else if (!subTestCd.equals(other.subTestCd))
return false;
return true;
}
}
And use it in the entity as follows:
#Entity
#Table(name="RAW_SCORE")
#IdClass(TestEntityPK.class)
public class TestEntity {
#Id private String ssn;
#Id
#Column(name="SUB_TEST_CD")
private String subTestCd;
#Column(name="TEST_QY")
private short testQy;
#Column(name="SYS_REC")
#Temporal(TemporalType.DATE)
private Date sysRec;
#Column(name="SYS_ID")
private String sysId;
// getters and setters
}

SAP UI5 application consuming Odata service : object is not an instance of declaring class

I have created a odata service
http://localhost:8080/carandodatabaseodata/emplist.svc/
when I access above URL it correclty shows me entity sets.
<service xmlns="<LINK>2007/app" xmlns:atom="<LINK>2005/Atom" xml:base="<SAME URL AS ABOVE>carandodatabaseodata/emplist.svc/">
<workspace>
<atom:title>Default</atom:title>
<collection href="ZaeScaleprinters">
<atom:title>ZaeScaleprinters</atom:title>
</collection>
</workspace>
</service>
I am also able to correctly see metadata information
below url is working fine.
carandodatabaseodata/emplist.svc/$metadata
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0">
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="carandodatabaseodata">
<EntityType Name="ZaeScaleprinter">
<Key>
<PropertyRef Name="Printer" />
<PropertyRef Name="Scale" />
<PropertyRef Name="Werks" />
</Key>
<Property Name="Printer" Type="Edm.String" Nullable="false" MaxLength="120" />
<Property Name="Scale" Type="Edm.String" Nullable="false" MaxLength="60" />
<Property Name="Werks" Type="Edm.String" Nullable="false" MaxLength="12" />
</EntityType>
<EntityContainer Name="carandodatabaseodataContainer" m:IsDefaultEntityContainer="true">
<EntitySet Name="ZaeScaleprinters" EntityType="carandodatabaseodata.ZaeScaleprinter" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
But when I am trying to access actual entityset using
carandodatabaseodata/emplist.svc/ZaeScaleprinters
it is giving me below error
<error xmlns="<LINK>/ado/2007/08/dataservices/metadata">
<code/>
<message xml:lang="en">
"sun.reflect.NativeMethodAccessorImpl: object is not an instance of declaring class. "
</message>
</error>
UPDATE : I am pasting java code also.
package com;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
import org.apache.olingo.odata2.processor.api.jpa.ODataJPAServiceFactory;
import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
public class ZAE_SCALEPrinterServiceFactory extends ODataJPAServiceFactory {
private static final String PERSISTENCE_UNIT_NAME = "carandodatabaseodata";
#Override
public ODataJPAContext initializeODataJPAContext()
throws ODataJPARuntimeException {
ODataJPAContext oDatJPAContext = this.getODataJPAContext();
try {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
oDatJPAContext.setEntityManagerFactory(emf);
oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
return oDatJPAContext;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
THE entity classes :
package model;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the ZAE_SCALEPRINTER database table.
*
*/
#Entity
#Table(name="ZAE_SCALEPRINTER")
public class ZaeScaleprinter implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private ZaeScaleprinterPK id;
public ZaeScaleprinter() {
}
public ZaeScaleprinterPK getId() {
return this.id;
}
public void setId(ZaeScaleprinterPK id) {
this.id = id;
}
}
package model;
import java.io.Serializable;
import javax.persistence.*;
/**
* The primary key class for the ZAE_SCALEPRINTER database table.
*
*/
#Embeddable
public class ZaeScaleprinterPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(unique=true, nullable=false, length=12)
private String werks;
#Column(unique=true, nullable=false, length=60)
private String scale;
#Column(unique=true, nullable=false, length=120)
private String printer;
public ZaeScaleprinterPK() {
}
public String getWerks() {
return this.werks;
}
public void setWerks(String werks) {
this.werks = werks;
}
public String getScale() {
return this.scale;
}
public void setScale(String scale) {
this.scale = scale;
}
public String getPrinter() {
return this.printer;
}
public void setPrinter(String printer) {
this.printer = printer;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof ZaeScaleprinterPK)) {
return false;
}
ZaeScaleprinterPK castOther = (ZaeScaleprinterPK)other;
return
this.werks.equals(castOther.werks)
&& this.scale.equals(castOther.scale)
&& this.printer.equals(castOther.printer);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.werks.hashCode();
hash = hash * prime + this.scale.hashCode();
hash = hash * prime + this.printer.hashCode();
return hash;
}
}

Hibernate Query Syntax exception : org.hibernate.hql.ast.QuerySyntaxException: unexpected token

I have a query where i am joining two tables ROuteMaster and RouteHalts.
When i perform inner join i am getting
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: on near line 1,
column 169 [SELECT rm.id , rm.routeCode , rm.startPlaceId , rm.endPlaceId ,
rm.active, rm.linkedRoute FROM com.oprs.pojo.routes.RouteMaster rm INNER JOIN
RouteHalts rh on rm.id = rh.routeId WHERE rh.placeId = :PlaceId
ORDER BY rm.id ASC]
I searched through the site and found similar question and the response for it. the question referred was
Hibernate: org.hibernate.hql.ast.QuerySyntaxException: unexpected token
I have many-to-one mapping in RouteHalts for RouteMaster, I have defined getter and setter methods for RouteMaster in RouteHalts
<many-to-one name="RouteMaster" class="com.oprs.pojo.routes.RouteMaster"
fetch="join"
foreign-key="id" column="ROUTE_ID" insert="false"
update="false" lazy="false" />
but still getting the same error. Can please some one guide me.
Mapping files
<hibernate-mapping package="com.oprs.pojo.routes">
<!-- Hibernate mapping for RouteMaster table -->
<class name="RouteMaster" table="OPRS_ROUTE_MASTER">
<id name="id" column="ROUTE_ID" type="java.lang.Long">
<generator class="assigned" />
</id>
<property name="startPlaceId" column="START_PLACE_ID"/>
<property name="endPlaceId" column="END_PLACE_ID"/>
<property name="routeCode" column="ROUTE_CODE"/>
<property name="routeName" column="ROUTE_NAME"/>
<property name="active" column="IS_ACTIVE"/>
<property name="linkedRoute" column="LINKED_ROUTE"/>
<property name="returnRouteId" column="RET_ROUTE_ID"/>
<!-- Auditor Information -->
<component name="auditor" class="com.oprs.pojo.base.Auditor">
<property name="createdBy" column="CREATED_BY" />
<property name="createdDate" column="CREATED_DATE" />
<property name="modifiedBy" column="MODIFIED_BY" />
<property name="modifiedDate" column="MODIFIED_DATE" />
</component>
<many-to-one name="RouteHalts" class="com.oprs.pojo.routes.RouteHalts" fetch="join"
foreign-key="routeId" column="ROUTE_ID" insert="false"
update="false" lazy="false" />
</class>
<!-- Hibernate mapping for RouteHalts table -->
<class name="RouteHalts" table="OPRS_ROUTE_HALTS">
<id name="id" column="HALTS_ID" type="java.lang.Long">
<generator class="assigned" />
</id>
<property name="routeId" column="ROUTE_ID"/>
<property name="placeId" column="PLACE_ID"/>
<property name="seqNo" column="SEQ_NO"/>
<property name="distanceKM" column="DISTANCE_KM"/>
<property name="border" column="IS_BORDER"/>
<property name="tolls" column="NO_OF_TOLLS"/>
<!-- Auditor Information -->
<component name="auditor" class="com.oprs.pojo.base.Auditor">
<property name="createdBy" column="CREATED_BY" />
<property name="createdDate" column="CREATED_DATE" />
<property name="modifiedBy" column="MODIFIED_BY" />
<property name="modifiedDate" column="MODIFIED_DATE" />
</component>
</class>
POJO of Route Master
public class RouteMaster extends Persistent {
private static final long serialVersionUID = -5710336066048392949L;
private Long startPlaceId;
private Long endPlaceId;
private Long returnRouteId;
private String startPlaceCode;
private String endPlaceCode;
private String startPlaceName;
private String endPlaceName;
private String routeCode;
private String routeName;
private String active;
private Auditor auditor;
private boolean revervseRoute;
private String linkedRoute = AppConstants.N;
private Map<Double, RouteHalts> haltsMap;
private RouteHalts routeHalts;
public RouteHalts getRouteHalts() {
return routeHalts;
}
public void setRouteHalts(RouteHalts routeHalts) {
this.routeHalts = routeHalts;
}
public Long getStartPlaceId() {
return startPlaceId;
}
public void setStartPlaceId(Long startPlaceId) {
this.startPlaceId = startPlaceId;
}
public Long getEndPlaceId() {
return endPlaceId;
}
public void setEndPlaceId(Long endPlaceId) {
this.endPlaceId = endPlaceId;
}
public String getStartPlaceCode() {
return startPlaceCode;
}
public void setStartPlaceCode(String startPlaceCode) {
this.startPlaceCode = startPlaceCode;
}
public String getEndPlaceCode() {
return endPlaceCode;
}
public void setEndPlaceCode(String endPlaceCode) {
this.endPlaceCode = endPlaceCode;
}
public Long getReturnRouteId() {
return returnRouteId;
}
public void setReturnRouteId(Long returnRouteId) {
this.returnRouteId = returnRouteId;
}
public String getRouteCode() {
return routeCode;
}
public void setRouteCode(String routeCode) {
this.routeCode = routeCode;
}
public Auditor getAuditor() {
return auditor;
}
public void setAuditor(Auditor auditor) {
this.auditor = auditor;
}
public String getStartPlaceName() {
return startPlaceName;
}
public void setStartPlaceName(String startPlaceName) {
this.startPlaceName = startPlaceName;
}
public String getEndPlaceName() {
return endPlaceName;
}
public void setEndPlaceName(String endPlaceName) {
this.endPlaceName = endPlaceName;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
public Map<Double, RouteHalts> getHaltsMap() {
return haltsMap;
}
public void setHaltsMap(Map<Double, RouteHalts> haltsMap) {
this.haltsMap = haltsMap;
}
public boolean isRevervseRoute() {
return revervseRoute;
}
public void setRevervseRoute(boolean revervseRoute) {
this.revervseRoute = revervseRoute;
}
public String getLinkedRoute() {
return linkedRoute;
}
public void setLinkedRoute(String linkedRoute) {
this.linkedRoute = linkedRoute;
}
public String getRouteName() {
return routeName;
}
public void setRouteName(String routeName) {
this.routeName = routeName;
}
}
POJO of RouteHalts
public class RouteHalts extends Persistent {
private static final long serialVersionUID = -1491637903595290895L;
private Long placeId;
private Long routeId;
private String placeCode;
private Double seqNo;
private Double distanceKM;
private boolean border;
private Auditor auditor;
private String placeName;
private String stateCode;
private String stopType;
private String departureTime;
private Integer tolls;
private String platformNo;
private Long stopTypeId;
private Integer linkSequenceNo;
private String actualTime;
private int arrivalDay;
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
public Long getRouteId() {
return routeId;
}
public void setRouteId(Long routeId) {
this.routeId = routeId;
}
public Long getPlaceId() {
return placeId;
}
public void setPlaceId(Long placeId) {
this.placeId = placeId;
}
public String getPlaceCode() {
return placeCode;
}
public void setPlaceCode(String placeCode) {
this.placeCode = placeCode;
}
public Double getDistanceKM() {
return distanceKM;
}
public void setDistanceKM(Double distanceKM) {
this.distanceKM = distanceKM;
}
public boolean isBorder() {
return border;
}
public void setBorder(boolean border) {
this.border = border;
}
public Auditor getAuditor() {
return auditor;
}
public void setAuditor(Auditor auditor) {
this.auditor = auditor;
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(String placeName) {
this.placeName = placeName;
}
public Double getSeqNo() {
return seqNo;
}
public void setSeqNo(Double seqNo) {
this.seqNo = seqNo;
}
public String getStopType() {
return stopType;
}
public void setStopType(String stopType) {
this.stopType = stopType;
}
public String getDepartureTime() {
return departureTime;
}
public void setDepartureTime(String departureTime) {
this.departureTime = departureTime;
}
public Integer getTolls() {
return tolls;
}
public void setTolls(Integer tolls) {
this.tolls = tolls;
}
public String getPlatformNo() {
return platformNo;
}
public void setPlatformNo(String platformNo) {
this.platformNo = platformNo;
}
public Long getStopTypeId() {
return stopTypeId;
}
public void setStopTypeId(Long stopTypeId) {
this.stopTypeId = stopTypeId;
}
public Integer getLinkSequenceNo() {
return linkSequenceNo;
}
public void setLinkSequenceNo(Integer linkSequenceNo) {
this.linkSequenceNo = linkSequenceNo;
}
public int getArrivalDay() {
return arrivalDay;
}
public void setArrivalDay(int arrivalDay) {
this.arrivalDay = arrivalDay;
}
public String getActualTime() {
return actualTime;
}
public void setActualTime(String actualTime) {
this.actualTime = actualTime;
}
}
You should not use explicit "JOIN ON" in HQL. Instead you can use implicit joining in HQL:
SELECT rm.id , rm.routeCode , rm.startPlaceId , rm.endPlaceId , rm.active , rm.linkedRoute
FROM com.abhibus.oprs.pojo.routes.RouteMaster rm
INNER JOIN rm.routeHalts rh WHERE rh.placeId = :PlaceId ORDER BY rm.id ASC
or you can use Theta style for writing join:
SELECT rm.id , rm.routeCode , rm.startPlaceId , rm.endPlaceId , rm.active , rm.linkedRoute
FROM com.abhibus.oprs.pojo.routes.RouteMaster rm, RouteHalts rh
WHERE rm.id = rh.routeId AND rh.placeId = :PlaceId ORDER BY rm.id ASC
Also you can execute your query as native SQL query, not HQL query. For this you should use
session.createSQLQuery(queryText);
instead of
session.createQuery(queryText);
And by the way, may be in your case in is better to fetch whole entity, not separated fields (columns)? For this you can use:
select rm from ...
This will return the List<RouteMaster> insted of List<Object[]>.
Change your query likes this;
SELECT rm.id, rm.routeCode, rm.startPlaceId, rm.endPlaceId, rm.active, rm.linkedRoute
FROM RouteMaster rm
INNER JOIN rm.routeHalts AS rh ON rm.id = rh.routeId
WHERE rh.placeId = :PlaceId
ORDER BY rm.id ASC

Hibernate mapping one-to-many problem

I am not very experienced with Hibernate and I am trying to create one-to-many mapping.
Here are relevant tables:
And here are my mapping files:
<hibernate-mapping package="com.xorty.mailclient.server.domain">
<class name="Attachment" table="Attachment">
<id name="id">
<column name="idAttachment"></column>
</id>
<property name="filename">
<column name="name"></column>
</property>
<property name="blob">
<column name="file"></column>
<type name="blob"></type>
</property>
<property name="mailId">
<column name="mail_idmail"></column>
</property>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.xorty.mailclient.server.domain.Mail" table="mail">
<id name="id" type="integer" column="idmail"></id>
<property name="content">
<column name="body"></column>
</property>
<property name="ownerAddress">
<column name="account_address"></column>
</property>
<property name="title">
<column name="head"></column>
</property>
<set name="receivers" table="mail_has_contact" cascade="all">
<key column="mail_idmail"></key>
<many-to-many column="contact_address" class="com.xorty.mailclient.client.domain.Contact"></many-to-many>
</set>
<bag name="attachments" cascade="save-update, delete" inverse="true">
<key column="mail_idmail" not-null="true"/>
<one-to-many class="com.xorty.mailclient.server.domain.Attachment"/>
</bag>
</class>
</hibernate-mapping>
In plain english, one mail has more attachments.
When I try to do CRUD on mail without attachments, everyting works just fine. When I add some attachment to mail, I cannot perform any CRUD operation.
I end up with following trace:
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at domain.DatabaseTest.testPersistMailWithAttachment(DatabaseTest.java:355)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`maildb`.`attachment`, CONSTRAINT `fk_Attachment_mail1` FOREIGN KEY (`mail_idmail`) REFERENCES `mail` (`idmail`) ON DELETE NO ACTION ON UPDATE NO ACTION)
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1666)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1082)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 27 more
Thank you
EDIT: On hvgotcodes proposal:
package com.xorty.mailclient.server.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.xorty.mailclient.client.domain.Account;
import com.xorty.mailclient.client.domain.AttachmentDTO;
import com.xorty.mailclient.client.domain.Contact;
import com.xorty.mailclient.client.domain.MailDTO;
/**
* Heavy weight Hibernate Mail
* #author MisoV
* #version 0.1
*/
public class Mail implements Serializable {
private List<Attachment> attachments = new ArrayList<Attachment>();
private String content;
private int id;
private boolean isNew;
private Account owner;
private String ownerAddress;
private Set<Contact> receivers = new HashSet<Contact>();
private String sender;
private String title;
/**
* Hibernate purposes
*/
public Mail() { // $codepro.audit.disable
}
/**
* Unwraps light DTO object to heavy Hibernate object.
* #param dto Corresponding DTO class.
*/
public Mail(final MailDTO dto) {
for (final AttachmentDTO attachmentDTO : dto.getAttachments()) {
attachments.add(new Attachment(attachmentDTO));
}
content = dto.getContent();
id = dto.getId();
isNew = dto.isNew();
owner = dto.getOwner();
ownerAddress = dto.getOwnerAddress();
receivers = dto.getReceivers();
sender = dto.getSender();
title = dto.getTitle();
}
/**
* Inserts new attachment
* #param attachment
*/
public void addAttachment(final Attachment attachment) {
attachments.add(attachment);
}
/* (non-Javadoc)
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Mail)) {
return false;
}
final Mail other = (Mail) obj;
if (attachments == null) {
if (other.attachments != null) {
return false;
}
} else if (!attachments.equals(other.attachments)) {
return false;
}
if (content == null) {
if (other.content != null) {
return false;
}
} else if (!content.equals(other.content)) {
return false;
}
if (id != other.id) {
return false;
}
if (isNew != other.isNew) {
return false;
}
if (owner == null) {
if (other.owner != null) {
return false;
}
} else if (!owner.equals(other.owner)) {
return false;
}
if (ownerAddress == null) {
if (other.ownerAddress != null) {
return false;
}
} else if (!ownerAddress.equals(other.ownerAddress)) {
return false;
}
if (receivers == null) {
if (other.receivers != null) {
return false;
}
} else if (!receivers.equals(other.receivers)) {
return false;
}
if (sender == null) {
if (other.sender != null) {
return false;
}
} else if (!sender.equals(other.sender)) {
return false;
}
if (title == null) {
if (other.title != null) {
return false;
}
} else if (!title.equals(other.title)) {
return false;
}
return true;
}
/**
* #return the attachments
*/
public List<Attachment> getAttachments() {
return attachments;
}
/**
* #return the content
*/
public String getContent() {
return content;
}
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #return the owner
*/
public Account getOwner() {
return owner;
}
/**
* #return the ownerAddress
*/
public String getOwnerAddress() {
return ownerAddress;
}
/**
* #return the receivers
*/
public Set<Contact> getReceivers() {
return receivers;
}
/**
* #return the sender
*/
public String getSender() {
return sender;
}
/**
* #return the title
*/
public String getTitle() {
return title;
}
/* (non-Javadoc)
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((attachments == null) ? 0 : attachments.hashCode());
result = prime * result + ((content == null) ? 0 : content.hashCode());
result = prime * result + id;
result = prime * result + (isNew ? 1231 : 1237);
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
result = prime * result
+ ((ownerAddress == null) ? 0 : ownerAddress.hashCode());
result = prime * result
+ ((receivers == null) ? 0 : receivers.hashCode());
result = prime * result + ((sender == null) ? 0 : sender.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
/**
* #return the isNew
*/
public boolean isNew() {
return isNew;
}
/**
* #param attachments the attachments to set
*/
public void setAttachments(final List<Attachment> attachments) {
this.attachments = attachments;
}
/**
* #param content the content to set
*/
public void setContent(final String content) {
this.content = content;
}
/**
* #param id the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* #param isNew the isNew to set
*/
public void setNew(final boolean isNew) {
this.isNew = isNew;
}
/**
* #param owner the owner to set
*/
public void setOwner(final Account owner) {
this.owner = owner;
}
/**
* #param ownerAddress the ownerAddress to set
*/
public void setOwnerAddress(final String ownerAddress) {
this.ownerAddress = ownerAddress;
}
/**
* #param receivers the receivers to set
*/
public void setReceivers(final Set<Contact> receivers) {
this.receivers = receivers;
}
/**
* #param sender the sender to set
*/
public void setSender(final String sender) {
this.sender = sender;
}
/**
* #param title the title to set
*/
public void setTitle(final String title) {
this.title = title;
}
}
Attachment:
// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString
/**
*
*/
package com.xorty.mailclient.server.domain;
import java.io.Serializable;
import java.sql.SQLException;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialException;
import com.xorty.mailclient.client.domain.AttachmentDTO;
/**
* Heavy weight Hibernate Attachment
* #author MisoV
* #version 0.1
*/
public class Attachment implements Serializable {
private static final long serialVersionUID = 2047475939737947104L;
private SerialBlob blob;
private byte[] content;
private String contentid;
private String contenttype;
private String filename;
private int id;
private int mailId;
/**
* Hibernate purposes
*/
public Attachment() { // $codepro.audit.disable emptyMethod
}
/**
* Unwraps DTO to heavy weight hibernate object.
* #param dto
*/
public Attachment(final AttachmentDTO dto) {
content = dto.getContent();
contentid = dto.getContentid();
contenttype = dto.getContenttype();
filename = dto.getFilename();
id = dto.getId();
mailId = dto.getMailId();
try {
blob = new SerialBlob(content);
} catch (final SerialException e) {
e.printStackTrace();
} catch (final SQLException e) {
e.printStackTrace();
}
}
/**
* #return the blob
*/
public SerialBlob getBlob() {
return blob;
}
/**
* #return the content
*/
public byte[] getContent() {
return content;
}
/**
* #return the contentid
*/
public String getContentid() {
return contentid;
}
/**
* #return the contenttype
*/
public String getContenttype() {
return contenttype;
}
/**
* #return the filename
*/
public String getFilename() {
return filename;
}
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #return the mailId
*/
public int getMailId() {
return mailId;
}
/**
* #param blob the blob to set
*/
public void setBlob(final SerialBlob blob) {
this.blob = blob;
}
/**
* #param content the content to set
*/
public void setContent(final byte[] content) {
this.content = content;
}
/**
* #param contentid the contentid to set
*/
public void setContentid(final String contentid) {
this.contentid = contentid;
}
/**
* #param contenttype the contenttype to set
*/
public void setContenttype(final String contenttype) {
this.contenttype = contenttype;
}
/**
* #param filename the filename to set
*/
public void setFilename(final String filename) {
this.filename = filename;
}
/**
* #param id the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* #param mailId the mailId to set
*/
public void setMailId(final int mailId) {
this.mailId = mailId;
}
}
EDIT2:
Hibernate actually performs insert:
insert into Attachment (name, file, mail_idmail, idAttachment) values (?, ?, ?, ?)
And values are correctly set. It doesn't fail on session.save nor on session.get (it even gets correct copy). It fails on committing transaction.
Only thing I can get of it is: Cannot add or update a child row: a foreign key constraint fails (maildb.attachment, CONSTRAINTfk_Attachment_mail1FOREIGN KEY (mail_idmail) REFERENCESmail(idmail) ON DELETE NO ACTION ON UPDATE NO ACTION)
you are getting a constraint violation exception. I think it is on the foreign key from attachment to mail, as evidenced by
foreign key constraint fails (`maildb`.`attachment`, CONSTRAINT `fk_Attachment_mail1` FOREIGN KEY (`mail_idmail`)
I noticed you are not specifying a generator for your id. See this documentation
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-id
since you did not specify the generator, the default is 'assigned' which means you have to programmatically assign the ids to the objects before you save them, which might or might not be what you want.
You didn't show us the code for how your Mail entity relates to the Attachment entity, or how you create your entities, which would all me to help more...depending on how you do it, hibernate might or might not be able to assign the foreign key in the attachment class.
EDIT -- from your comments, you are missing a few things. Try assigning the id of the mail entity to the attachment in your addAttachment method on mail. If you want the db to assign the id, you need to look up how to have the id column of the tables auto-increment for whatever RDBMS system you are using, and then you change add a generator to the id mappings of the entities. The generator will probably be 'identity' or 'increment' depending on the RDBMS.
As you want to make a bi-directionnal relation, you should indicate to your Attachment the Mail object and not only the Id :
In the Attcahment class, remove
private int mailId;
and replace it by
private Mail mail;
with the correct setter and getter.
In the Xml mapping file:
<property name="mailId">
<column name="mail_idmail"></column>
</property>
should be replaced by :
<many-to-one name="mail"
column="mail_idmail" not-null="true"/>
By the way, your hashCode/equals methods are crap.
You should read this : http://community.jboss.org/wiki/EqualsandHashCode
Anyway, it's better to not override them than have them wrong.

Categories

Resources