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?