tenwit wrote:
Of course you can use delegation to hide it. You have methods, associations etc. that hibernate is aware of and that you use in your HQL and Criteria, and you have public API methods that delegate. So when your API code is able to do "value = delegator.getValue()", the equivalent Criteria would have to be "crit = sess.createCriteria(Delegator.class).createAlias("priv").add(Restrictions.eq("priv.value", value))".
What I meant is that you need the exact path for ordering in the criteria API. Since I use DetachedCriteria I now have to adapt code on completely different place. I query a particular object and want to sort it by lastname, a property of user (or now contact). Despite that it actually
does not work it has to look like the following:
Code:
criteria.createAlias("user", "u").addOrder(Order.asc("u.lastname"));
changes to
Code:
criteria.createAlias("user.contact", "u").addOrder(Order.asc("u.lastname"));
Actually I need to know that there is a delegation - that's not what I consider a hidden detail.
tenwit wrote:
you can use joined-subclass. You'll need an abstract class for User which defines contactId as a property. Then your UserContact concrete class, defined as a joined-subclass, can use key column="contactId" property-ref="contactId".
I have now the following:
Code:
<class name="AbstractUser" abstract="true" table="user_">
<id name="id" column="userId">
<property name="contactId"/>
<joined-subclass name="User" table="contact_">
<key column="contactId" property-ref="contactId"/>
<property name="lastname" type="string"/>
</joined-subclass>
</class>
This seems not to work for two reasons:
1. It again tries to match the primary key of User_ with the primary key of Contact_. The same happened when using the former solution with <join>:
Code:
select ... from contact_ user0_ inner join user_ user0_1_ on user0_.contactId=user0_1_.userId where user0_.contactId=?
2. When searching for AbstractUser it fails since it tries to instantiate it. When searching for User it does not find them since it searches for them by contactId, not by userId. But I only have the userId. That's what you can access in a portlet by PortletRequest.getUserPrincipal() (as for HttpServletRequest).
But even if I get that one to work, is Hibernate mapping in anyway intuitive? I don't consider myself to be simple-minded, but I wonder how one should find out such a work-around. The original version was at least somehow documented in the reference.
tenwit wrote:
what if they change their model in the future to allow one user to have multiple rows in the Contact table?
That's unlikely since Contact_ contains all the data of the user like firstname, lastname, birthday etc. while User_ only contains the access data to the portal (username, password, number of failed logins, etc.) But anyway, I only need very few details from the user like email and name. What I tried to do with the Hibernate mapping is to hide the actual portal database details. You can prove me wrong (see above), but it seems not to be possible.
Joerg