Justin Kredible
Justin Kredible

Reputation: 8414

JPA 2.0: Load a subset of fields for an entity

I have an Entity named address. The address Entity has several fields, one of which is CITY. I've created a query by calling entityManager.createQuery but my query only includes the CITY field in the select clause (because I only want to load that field). The CITY field is of type String. When I get my resultList, I do not get a list of Address objects but instead a list of Object[].

Is there any way to have a list of Address created instead of a list of Object[]? My JPA provider is hibernate, latest version. I want a solution that does not require the use of anything Hibernate specific.

Upvotes: 8

Views: 8052

Answers (3)

user275801
user275801

Reputation: 1355

There is a way to do this, but it involves some duplication of code. You'll have to create a new entity called "AddressWithCityOnly" containing just the ID and the CITY attributes and point it to the same table in the db (address table).

Then you can use this new entity to do partial load of the Address entity (loading these entities will only load the CITY field) and partial update (will update only the CITY field) to the address table.

I am facing a similar issue. I have a PERSON table with about 70 columns and about 100,000 rows, and I want to update just one column of all of the rows. Loading the original entity would retrieve all 70 columns which is too much overhead.

Upvotes: 0

Jörn Horstmann
Jörn Horstmann

Reputation: 34034

This is possible with constructor expressions in your query. Normally you would use this with a custom DTO, but it should work with the entity too. First create an additional constructor in your entity taking only the needed fields:

public Address() {
    //default constructor
}

public Address(String city) {
    this.city = city;
}

Your query could then look like this:

select new your.package.Address(a.city) from Address a where ...

Note that the resulting object is not attached to the EntityManager, so changes to it won't be automatically persisted.

Upvotes: 14

JB Nizet
JB Nizet

Reputation: 692073

How would Hibernate load Address instances if you request for cities? JPA entities are objects, and objects are supposed to respect invariants. For example, one such invariant might be that an address always has an ID, a street, etc. If Hibernate loaded partial objects (with only the city attribute filled), those invariants would be broken and you could not rely on your own code anymore. You would also have all sorts of problems if you tried to attach such an Address to another object, or if you simply tried to remove it, because it wouldn't even has an ID anymore.

So the short answer is no : it's not possible.

The long answer is that since Adress is a POJO, you just have to create Addresses from the loaded cities by yourself, or by using a ResultTransformer. But you would get transient Address instances rather than attached Adress entities. This is a recipe for countless bugs and confusion, IMHO.

Upvotes: 2

Related Questions