3

Using following code I can successfully retrieve address fields of a user, to do that I need to define all its fields using Projection. Imagine address has 100 fields, in this case I have to define all of them.

I am wondering if I can return just address object of customer without defining all its fields in Proposition?

I know I can retrieve id of address and use that to retrieve its object, but I am wondering if there is ano other method rather than this or defining all its fields.

Hibernate

            .....
            Criteria cre = session.createCriteria(User.class, "user")
                    .createAlias("user.address", "addr");

            cre.add(Restrictions.eq("user.id", ID));

            ProjectionList pl = Projections.projectionList();
            pl.add(Projections.property("addr.id").as("id"));
            pl.add(Projections.property("addr.unit").as("unit"));
            .......
            cre.setProjection(pl);
            Address address = (Address) cre.list().get(0);

I used the following as well but it runs into error (could not resolve property: addr of: com.myProject.User)

    pl.add(Projections.property("addr").as("address"));

Java

@Entity
public Class User {

     @Id
     @GeneratedValue
     private long id;

     @OneToOne
     private Address address;

     ...
}
J888
  • 1,944
  • 8
  • 42
  • 76

4 Answers4

5

Use JPQL/HQL:

select a from User u join u.address a where u.id = :userId

The Criteria API is more limited than JPQL, and can't select any other entity than the root entity. It shouldn't be used if the query doesn't have to be dynamically composed. Of course, if the association is bidirectional, you can simply use

select a from Address a where a.user.id = :userId

or its equivalent Criteria:

Criteria c = session.createCriteria(Address.class, "a");
c.createAlias("a.user", "u");
c.add(Restrictions.eq("u.id", userId));
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • if I use JPQL would it conflict with the transactions of hibernate? – J888 Nov 18 '13 at 23:16
  • 1
    please also have a look at my other question thanks http://stackoverflow.com/questions/20059700/how-to-retrieve-those-reocrds-that-exists-in-a-specific-relationship – J888 Nov 18 '13 at 23:16
  • No, of course not. JPQL/HQL is the preferred way to execute JPA/Hibernate queries. Criteria is useful to compose queries dynamically. – JB Nizet Nov 19 '13 at 06:51
1

If the result you pull in from a query will match the fields of a DAO you have defined. I would just type-cast the result from an hql or native SQL query.

Select  * 
From Address a
where a.id = :userid

Address addrObject = (Address) query.uniqueResult();

Mason T.
  • 1,567
  • 1
  • 14
  • 33
1

Do like this

 Criteria criteria = session.createCriteria(User.class, "user")
              .createAlias("user.address", "addr")          
             .add(Restrictions.eq("user.id", userId))            
             .setProjection(Projections.property("addr"));

 Address address = (Address) criteria.list().get(0);
Prabhakaran Ramaswamy
  • 25,706
  • 10
  • 57
  • 64
1

Couple of options:

  1. use lazy="false" for Address object. If you have to use lazy=true for some reason, you can run this query in a separate session and override the lazy behavior in that session.
  2. Use the database specific query to get a list of field names and then dynamically generate Projections by looping through the field names.

For example, In mysql

SHOW COLUMNS FROM Address

In postgres

SELECT * FROM information_schema.columns
WHERE table_schema = your_schema
AND table_name   = your_table

I hope this helps.

gmansoor
  • 509
  • 1
  • 4
  • 12