Hibernation Polymorphism: Creating the Right Class

I'm new to hibernation, as you will see soon. I apologize if this question has an easy answer, but I'm just not familiar with all the terminology to find it easily.

Let's say I have a base class "A" and one subclass of "B" that I map to Hibernate, possibly using a table for each strategy of the subclass. The base class is not abstract. All Bs are As, but not all As are Bs. This is reflected in the database, where table B refers to table A.

Ok, now suppose I have some kind of program that displays a list of objects A. A user can select any object A and take it to the screen to change it ... BUT, if object A is also B, the screen will allow the user modify B, not just A.

How in the world am I approaching this?

Note. I am not asking how to determine which class is an object. I ask how do I get hibernate to return a list of objects that belong to the corresponding class.

+7
java orm hibernate
source share
3 answers

I apologize again for this question. I am very surprised how sleep mode works, it is really great. I did not think that this would do it all automatically, and I really was not even sure what I was trying to ask. When I answered the comments, I began to refine this question in my head and was able to then find the answer I was looking for. Thanks to everyone who helped.

Answer: hibernate does this automatically.

Suppose your database table A has a primary key id, and table B has a primary key called a_id that refers to table A.

So, you create the following classes (in abbreviated form):

public class A { private String aProperty; // ... getter and setter, etc { public class B extends A { private String bProperty; // ... getter and setter, etc } 

Then map them like this:

 <hibernate-mapping> <class name="A" table="a" catalog="testokdelete"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="aProperty" column="a_property"/> <joined-subclass name="B" table="b"> <key column="a_id"/> <property name="bProperty" column="b_property"/> </joined-subclass> </class> </hibernate-mapping> 

And you can return objects A and B with a simple query "from A", as in the following code:

 Query query = session.createQuery("from A"); List<Object> objects = query.list(); for (Object object: objects) { System.out.print("A property: "); System.out.print(((A)object).getAProperty()); System.out.print(", B property: "); System.out.println( (object.getClass() == B.class) ? ((B)object).getBProperty() : "not a B"); } 

All he does is return a list of objects using the query "from A", and then scan them, printing aProperty from our class A, and if the class is of type B, bProperty from our class B.

The sleep request in this case is automatically polymorphic and, if necessary, will give you object B.

+6
source share

You can use RTTI with an instance, but not an object oriented one.

Instead, give base class A method that relates to what a B does, for example, if A Customer and B is PreferredCustomer , the method can be isPreferredCustomer() .

In A method returns false, in B it returns a rotation.

It is important to note that we are not asking if the object has a particular class; we ask a business question by asking an object if it can do something. This is a subtle but important difference.

In particular, this means that your code below will not change when and if you add additional Customer subclasses, if each subclass truthfully answers the question, isPreferredCustomer() .

In your code:

 if( a.isPreferredCustomer() ) { showPreferredCustomerPage( a) ; else { show CustomerPage(a); } 

You might find it even better to give the Customer a showPage() method, but that ties your models too much to your views.

Instead, you put the above code in some ViewDispatcher class, which can change orthogonally with the Client and its subclasses.

For example, you may have several subclasses of ViewDispatcher , some of which relate to PreferredCustomer , and some not.

+2
source share

Ok, I'm going to assume that your classes are mapped correctly. If you have done this, you can do the following:

 public List<A> getAllClassA(){ Session session = HibernateUtil.getSession(); Criteria criteria = session.createCriteria(A.class); List<A> ret = criteria.list(); return ret; } 

If you are not familiar with the criteria, it is quite easy to pick it up. This piece of code will retrieve all the objects of class A from the database. If you set up the map correctly, I think Hibernate will also support the B attributes of your A objects if they are actually B objects (sorry if this is confusing).

Let me know if it was, you were looking for or you need code for HibernateUtil.

+1
source share

All Articles