-->
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.  [ 4 posts ] 
Author Message
 Post subject: Force many to one without loading - no matter what?
PostPosted: Fri Nov 05, 2010 6:35 pm 
Regular
Regular

Joined: Sat Jan 22, 2005 6:57 pm
Posts: 50
Location: Chicago
I have a situation where I would like to have a many-to-one relationship on an attribute to get my HSQL and Criteria objects to work, however, I NEVER want it to load the object in any result?

I have seen how you can use proxy type lazy settings, but those will load if the method is called. In my case, I want those attributes to ALWAYS be null.

is there a way to do this in configuration?

For example, if I had a hibernate mapping file with the following defined:

Code:
      <many-to-one name="foo" column="foo" lazy="never" update="false"
         fetch="select" outer-join="false"  cascade="none"/> 


I would want to be able to use foo in Criteria like this:

Code:
Criteria criteria = session.createCritera(MyClass.class);
criteria.add(Restrictions.eq("foo", "fa"));
MyClass result = criteria.uniqueResult();
Foo foo = result.getFoo();


And I want "foo" to be null, ALWAYS.

I gave an example above with my lazy="never" but obviously there is no such thing. Anyone have any ideas?


Top
 Profile  
 
 Post subject: Re: Force many to one without loading - no matter what?
PostPosted: Sun Nov 07, 2010 4:14 am 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
You do not want to abuse Hibernate in such way. Just use lazy="true" and improve your architecture to not rely on any special tricks. Wanting such special custom behavior of fields is a clear indication that your architecture is bad.


Top
 Profile  
 
 Post subject: Re: Force many to one without loading - no matter what?
PostPosted: Sun Nov 07, 2010 11:37 am 
Regular
Regular

Joined: Sat Jan 22, 2005 6:57 pm
Posts: 50
Location: Chicago
Wow... that is a harsh statement.

Hibernate is not perfect. Its architecture forces you to break object oriented rules from time to time in order to improve performance. Here, in my opinion, is a classic example of such a situation:

Code:
public class Account {
    private String id;
    private String region;
    private List<User> users;

    // getters / setters
}

public class User {
    private String id;
    private Account account;
    // other ids
}


Now say I create a many-to-one relationship, or some other relationship, where I tell hibernate to LAZY load the list of Users in the Account object, and only because hibernate requires it, I have to create an account attribute in my User object. Why? Say I want to do this sort of thing:

Code:
     Session session = ...
     Criteria criteria = session.createCriteria(User.class);
     criteria.createAlias("account", "account");
     criteria.add(Restrictions.eq("account.region", "Midwest");
     criteria.list();


The code above asks Hibernate to give me all users whose account is in the midwest region. Unless I decide to de-normalize my table structure and put the midwest region in my User table - which would then force me to only allow a 1:1 relationship between User & Account (which may not be true, a user *could* belong to more than one account) - I HAVE to screw up my data model to satisfy hibernate. OR, I could just just vanilla SQL and say "Select * from users were accountID in (select id from accounts where region = 'midwest').

Ideally, especially in the above scenario, I ONLY WANT THE ID, not the full object. In a perfect world, I would be able to do this sort of java data representation instead:

Code:
public class Account {
    private AccountID id;
    private String region;
    private List<UserID> userIDs;

    // getters / setters
}

public class User {
    private UserID id;
    private AccountID accountID;

    // getters / setters
}


Where I use IDs only, not full objects, but the HSQL or Criteria would still allow me to do the relational joins.

Also, there is another problem with lazy loading that many people have issues with. If you require such types of criteria queries where you need to reference attributes from other classes in your criteria, and you make them all lazy, then you run into a BIG problem when you decide you need to pass that returned object across tiers in an application stack. Since the object leaves the session scope, and goes into another process, you start getting all these lazy exceptions because other programs and other systems may not even use Hibernate, but see the methods available and start making calls to it... requiring all systems outside of yours to know and understand hibernate - which is a BAD architectural problem.

In my original request, I was asking how NOT to load in an object... because I figured there was no way to just return IDs but still get use of the hibernate query syntax. If there is a way to do that, then I am all ears.


Top
 Profile  
 
 Post subject: Re: Force many to one without loading - no matter what?
PostPosted: Sun Nov 07, 2010 6:32 pm 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
I would say that in this case you need to consider Hibernate as a smart database access API. It is somewhat smarter than pure JDBC, but it still does not make all relational database routines object-oriented or extremely elegant. In my opinion, the requirements Hibernate makes to link one object to another are not performance related. The problem is that Hibernate tries to recreate the whole database on the client level and hide underlying database fully. That is why it is very natural that all possible relations should also be present in the mapping.

Let return to your particular problem now :) How about using "field" level access to all your special fields (like "user.account")? That is to set "access" property to the "field" value. You would be able to remove all the public getters and setters then and nobody will notice that your object has some interesting abnormalities hidden inside.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

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.