AF
HomeTagSubmit NotesAsk AnythingLoginSubscribe Us
AF
1. Feel Free to ask and submit anything on Anyforum.in and get satisfactory answer
2. Registration is not compulsory, you can directly login via google or facebook
3. Our Experts are looking for yours ?.



hibernate-basics: Why should not we declare persistent class as final?

Please explain the reason behind keeping persistent class as non-final.

hibernate x 23
basics x 171
Posted On : 2014-07-16 16:44:35.0
profile Garima Gupta - anyforum.in Garima Gupta
596129554553
up-rate
5
down-rate

Answers


Yes, you can make an Hibernate Entity class final, but that´s not good. Since Hibernate uses proxy pattern for performance improvement in case of lazy association, as we know that final class cannot be inherited. So keeping persistent class as final means to explicitly disable proxy generation by adding @Proxy(lazy=false), thus limiting your performance improvement options. Though, you can avoid this penalty, if your persistent class is an implementation of interface, which declares all public methods defined in Entity class.

So if you really want or need to make your classes final, you can do it by having your entity implement an interface that declares all of its public methods, but I´ve never done that and really would rather not since the less I have to do, the better.

Following is the scenario we are talking about:
------------------------------------------------------------------

@Test
public void finalNoProxy() throws Exception {
SessionFactory sessFac = HibernateUtil.getSessionFactory();
Session sess = null;
Transaction trx = null;
try {
sess = sessFac.openSession();
trx = sess.beginTransaction();

SpokeInFinalWheel spoke = (SpokeInFinalWheel)
sess.load(SpokeInFinalWheel.class, finalSpokeId);

FinalWheel wheel = spoke.getWheel();

assertFalse((Object) wheel instanceof HibernateProxy);

trx.commit();
} catch (Exception e) {
HibernateUtil.rollbackQuietly(trx);
throw e;
} finally {
HibernateUtil.closeQuietly(sess);
}
}



And here is the SQL:
-------------------------------

Hibernate:
/* load com.github.snd297.finalentities.model.SpokeInFinalWheel */ select
spokeinfin0_.id as id2_0_,
spokeinfin0_.version as version2_0_,
spokeinfin0_.wheel as wheel2_0_
from
spoke_in_final_wheel spokeinfin0_
where
spokeinfin0_.id=?
Hibernate:
/* load com.github.snd297.finalentities.model.FinalWheel */ select
finalwheel0_.id as id1_0_,
finalwheel0_.version as version1_0_,
finalwheel0_.bicycle as bicycle1_0_
from
final_wheel finalwheel0_
where
finalwheel0_.id=?
Hibernate:
/* load com.github.snd297.finalentities.model.FinalBicycle */ select
finalbicyc0_.id as id0_0_,
finalbicyc0_.version as version0_0_
from
final_bicycle finalbicyc0_
where
finalbicyc0_.id=?


See how even though we only asked for a spoke, we got the wheel and the bicycle too?

Let´s fix this broken spoke by making a new Spoke that points at a non-final Wheel:

@Entity
public class Wheel extends LongIdAndVersion {

private Set<Spoke> spokes = newHashSet();

@OneToMany(
mappedBy = "wheel",
cascade = CascadeType.ALL,
orphanRemoval = true)
public Set<Spoke> getSpokes() {
return spokes;
}
//...
}

===========================================================================
@Entity
public class Spoke extends LongIdAndVersion {
private Wheel wheel;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
public Wheel getWheel() {
return wheel;
}
//...
}



Test it:
----------------
@Test
public void proxy() throws Exception {
SessionFactory sessFac = HibernateUtil.getSessionFactory();
Session sess = null;
Transaction trx = null;
try {
sess = sessFac.openSession();
trx = sess.beginTransaction();

Spoke spoke =
(Spoke) sess.load(Spoke.class, spokeId);

Wheel wheel = spoke.getWheel();

assertTrue(wheel instanceof HibernateProxy);
assertFalse(Hibernate.isInitialized(wheel));

trx.commit();
} catch (Exception e) {
HibernateUtil.rollbackQuietly(trx);
throw e;
} finally {
HibernateUtil.closeQuietly(sess);
}
}


And the generated SQL:
---------------------------------------
Hibernate:
/* load com.github.snd297.finalentities.model.Spoke */ select
spoke0_.id as id3_0_,
spoke0_.version as version3_0_,
spoke0_.wheel as wheel3_0_
from
spoke spoke0_
where
spoke0_.id=?



Look at that, we got the Wheel proxy and only the SQL we wanted.

And there you have it.

Posted On : 2014-07-16 17:30:05
Satisfied : 1 Yes  0 No
profile Rishi Kumar - anyforum.in Rishi Kumar
523188245674
Reply This Thread
up-rate
5
down-rate



Post Answer
Please Login First to Post Answer: Login login with facebook - anyforum.in