For example the Site mapping will resemble something like this;
@Entity
@Table(name = "site")
public class Site
{
private Partner partner;
public Site()
{
super();
}
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "partnerid", nullable = true)
public Partner getPartner()
{
return partner;
}
public void setPartner(Partner partner)
{
this.partner = partner;
}
}
While the Partner object mapping will resemble something like this;
@Entity
@Table(name = "partner")
public class Partner
{
private List<Site> sites;
public Partner()
{
super();
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "partner")
public List<Site> getSites()
{
return sites;
}
public void setSites(List<Site> sites)
{
this.sites = sites;
}
}
From the above mappings, you'll notice that Partner has been mapped to Site using the partnerid of MySQL Table partner. A physical schema for partner and site Tables looks like this;
Partner: +-----------+-------------+------+-----+ | Field | Type | Null | Key | +-----------+-------------+------+-----+ | id | int(11) | NO | PRI | | name | varchar(50) | NO | | +-----------+-------------+------+-----+
Site: +-----------+-------------+------+-----+ | Field | Type | Null | Key | +-----------+-------------+------+-----+ | id | int(11) | NO | PRI | | sitename | varchar(50)| NO | | | partnerid | int(11) | NO | | +-----------+-------------+------+-----+
Because the PartnerID is integer if you have a method say getParent() in Site for example like this;
@Transient
public Company getParent()
{
if (!(getPartner() == null))
{
return getPartner();
}
return null;
}
In MySQL , default integer is '0' , not NULL. This will cause Hibernate String to load a Partner with non-existent row with id=0 and therefore throw:
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.lop.testing.Partner#0]at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:409)at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:108)at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:97)at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)at com.essensys.bluefin.Partner_$$_javassist_10.toString(Partner_$$_javassist_10.java)at java.lang.String.valueOf(String.java:2826) at java.lang.StringBuilder.append(StringBuilder.java:115)
To resolve this, simply annotate the Site getPartner() method as shown below;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "partnerid", nullable = true)
@NotFound(action = NotFoundAction.IGNORE)
public Partner getPartner()
{
return partner;
}
The existance
@NotFound(action = NotFoundAction.IGNORE)fix the issue.
Job done! but then the question is, do you need to go through that?