-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Polymorphic mapping using interfaces
PostPosted: Sat Nov 29, 2003 12:32 pm 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
Hi everyone,

I have three classes Company, Division and SubDivision all implementing the interface DirectedUnit and one more Class Director. What I wish to do is a to map a relation (in this special case a one to one relation, but this is just an example and I'd like to keep the disussion more general) between DirectedUnit and Director.

My favorite solution would be: one table for Company, another one for Division, a third one for SubDivision and no table for DirectedUnit as it is just an interface. However this seems not to be possible, as I have to declare a mapping for DirectedUnit to be able to map the association between DirectedUnit and Director. And once I have this mapping, Hibernate will query the DB for the specified table.

So my current solution is to create a dummy table for DirectedUnit, that contains only a primary key column. As this table is alway empty, Hibernate never tries to instantiate a DirectedUnit (that would of course fail, since DirectedUnit is an interface).

Theoretically I'm happy. When I do queries like

Code:
select du from DirectedUnit du where ...


I get what I want. But when I select a Director, the only table searched for it's directed unit is my dummy DirectedUnit table, which is of course empty. Hibernate does not look for other directed units in Company, Division or SubDivision, where it would acutally find the directed unit for my director.

Is the hibernate mapping less polymorphic than HQL? Am I missing something?

I know that there are other ways to map things like this. I'm aware I could use subclasses or any-mappings. But I'd like to know if there is a possibility to keep the basic idea of my mapping and get things done with it.

Thanks in advance for any hints.

Peter


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 29, 2003 12:40 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Do you know about <any> and horribly named <many-to-any>?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 29, 2003 1:36 pm 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
gavin wrote:
Do you know about <any> and horribly named <many-to-any>?


Yes, I know about these special mappings. But in the reference manual, I found the interesting statement:
Quote:
... and should also be used rarely, if ever.
.

If I understood things well, Hibernate has to query each single table to find the matching elements. Is this true? This would explain the statement in the reference doc and would certainly disqualify this kind of mapping for our apps.

Perhaps, I misunderstood the <any> and <many-to-any> mappings. In this case, I would be thankful for any hints on the right usage these mappings.

Regards,

Peter


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 29, 2003 9:29 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
The reasons that <any> mappings are not recommended are:

(1) there is no foreign key constraint, so ensuring integrity is more difficult
(2) we cannot do outerjoin fetching
(3) polymorphic association querying is not possible


Quote:
If I understood things well, Hibernate has to query each single table to find the matching elements. Is this true?


I'm not sure quite what you mean by this .... I don't think so ....


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 29, 2003 9:30 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Of course, the other solution is to map all the concrete classes as <joined-subclass>es of the interface.


Top
 Profile  
 
 Post subject: interface mapping problem
PostPosted: Sun Nov 30, 2003 4:30 pm 
Newbie

Joined: Sun Nov 30, 2003 4:46 am
Posts: 17
Hi,

My confusion regarding interface mapping is that an interface can have variables that should be constants.

Then how can we map an interface to a dummy table that has a primary key, like the scenario mentioned in this topic. Because we'll also have to declare the primary key in the <id> tag of the interface's mapping file. and in the <id> tag we'll have to define the identifier property which cannot be declared in the Java interface.

And What if the interface is involved in a bidirectional one to many relationship, with interface at the many end. Then the interface should also contain a reference to its parent. so how will this relationship be mapped in case of an interface being involved?

Thanx in advance for any suggestions and tips[/b]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 30, 2003 11:40 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
An interface can have a property. A property is just a get/set pair!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 9:55 am 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
I'm sorry, I have to repost for the polymorphic mapping matter. This is a key feature for us. So I'll try to explain the situation.

We have an existing application an we're thinking about to migrate it to hibernate. Our current application uses the table per concrete class mapping strategy for several reasons. One of the most important reason is performance. I'll give an example: We have a huge table of Addresses (2 million rows) and a smaller table of specialized PersonAddresses. Using the table per concrete class strategy, we have thus very good performance when searching for, inserting or updating PersonAddresses. This benefit outweights by far the slight performance disadvantage when searching over die Address superclass, where a table per joined subclass or table per class hierarchy would possibly be a little faster.

What we are doing is not really a someclass-to-anyclass mapping, but a someclass-to-someclasshierarchy mapping, just like hibernate mappings using <joined-subclass> or <subclass> but with a table per concrete class strategy.

Our database is shared by different applications, so we can not alter the database significantly.

Has anyone suggestions on how to integrate this with hibernate. In fact, I think it theoretically works. When I query the DB using HQL, hibernate provides all the polymorphism I need. It just seems that the mapping does not provide support for the case I described above.

I would be greatful for any help or suggestion. I'm really stuck at this point.

Peter


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 10:02 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
And we still don't know what your problem is!

Hibernate is perfectly able to cope with this kind of mapping!


You don't need any special mapping, just use <class>. If you want polymorphic relationships, use <any>.

Sorry, I'm stumped. You have to be much more explicit about what you think is missing here.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 10:11 am 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
gavin wrote:
Sorry, I'm stumped. You have to be much more explicit about what you think is missing here.


Ok. Then it's the <any>-mapping that I do not understand. Is there any example for this kind of mapping? Could anyone who uses this kind of mapping give me some hints?

And what about the other direction. I could not find a mapping with an any-type at the n-side. Am I wrong?

I'm sorry to bother you with this stuff, I really do not get it.

Peter


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 10:30 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Code:
<class name="Foo" ...>
   <id name="id" type="long">
      ....
   </id>
   ....
</class>

<class name="Bar" ...>
   <id name="id" type="long">
      ....
   </id>
    ...
</class>

<class name="X">
   ....
   <any id-type="long" meta-type="class">
      <column name="referenced_class"/>
      <column name="foo_or_bar_id"/>
   </any>

</class>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 11:14 am 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
What follows is an example mapping to illustrate my problem.

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
  <class
    name="de.armax.spielwiese.entity.Address"
    table="Address">
    <id name="oID" type="string" column="adrOID" access="field">
      <generator class="uuid.hex"/>
    </id>
    <property column="adrAttribute" type="string" name="attribute" access="field"/>
    <many-to-one
      cascade="none"
      class="de.armax.spielwiese.entity.Order"
      name="order" column="adrOrderOID"
      access="field"/>
  </class>

  <class
    name="de.armax.spielwiese.entity.PersonAddress"
    table="PersonAddress">
    <id name="oID" type="string" column="padOID" access="field">
      <generator class="uuid.hex"/>
    </id>
    <property column="padAdditionalAttribute" type="string" name="additionalAttribute" access="field"/>
    <many-to-one
      cascade="none"
      class="de.armax.spielwiese.entity.Person"
      name="person" column="padPersonOID"
      access="field"/>
  </class>

  <class
    name="de.armax.spielwiese.entity.Order"
    table="Orders">
    <id name="oID" type="string" column="ordOID" access="field">
      <generator class="uuid.hex"/>
    </id>
    <property column="ordOrderAttribute" name="orderAttribute" access="field"/>
    <set lazy="true" cascade="none" access="field"
      name="addresss"
    >
      <key column="adrOrderOID"/>
      <one-to-many
        class="de.armax.spielwiese.entity.Address"/>
    </set>
  </class>

  <class
    name="de.armax.spielwiese.entity.Person"
    table="Person">
    <id name="oID" type="string" column="psOID" access="field">
      <generator class="uuid.hex"/>
    </id>
    <property column="psName" name="name" access="field"/>
    <set lazy="true" cascade="none" access="field"
      name="personAddresss"
    >
      <key column="padPersonOID"/>
      <one-to-many
        class="de.armax.spielwiese.entity.PersonAddress"/>
    </set>
  </class>
</hibernate-mapping>


PersonAddress is a subclass of Address. Order holds a set of Addresses that could be instances of Address or PersonAddress. And thats the problem. Hibernate does not look in the PersonAddress table for child addresses for order (quite logical, since I specify the key column of table Address in the one-to-many mapping Order -> Address. So my question is not "why doesn't this work?" but "how do I get this work?".

I don't think that <any>-mapping helps in this case.

I hope I was more comprehensible this time.

Peter


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 11:16 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
You need to use <many-to-any>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 11:20 am 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
I add the SQL generated by hibernate when trying to save on Order instance and one PersonAddress instance linked together:

Code:
insert into Orders (ordOrderAttribute, ordOID) values ('A order attribute.', '402880f7f9376c0000f9376c02d30001')
insert into PersonAddress (padAdditionalAttribute, padPersonOID, padOID) values ('A additional attribute', '', '402880f7f9376c0000f9376c02d30002')
update Address set adrOrderOID='402880f7f9376c0000f9376c02d30001' where adrOID='402880f7f9376c0000f9376c02d30002'


It seems like hibernate thinks of Address and PersonAddress as joined subclasses?!? I do not understand this, but perhaps someone who is more familiar with hibernate mappings can get some hints out of this.[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 11:22 am 
Newbie

Joined: Thu Nov 13, 2003 1:14 pm
Posts: 18
Location: Leinfelden-Echterdingen, Germany
gavin wrote:
You need to use <many-to-any>


Hmm, so I have to replace the <one-to-many> by <many-to-any>. Seems strange to me. Isn't it more likely something like <any-to-many>? Because the 1-end is well known. It is the n-side of the association that has different types.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.