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.