0

This has always been an annoyance with Hibernate / JPA and now trying to see if there is a way around this limitation.

Basically given a Store and User ... say a Store has many users.

I prefer Store declared manually in a Store table, and users in a User table. The connection is in a StoreUser table.

You repeat this for a number of this, StoreAddress, StoreEmployee and so on and you have a bunch of things.

However, for the common case of getting everything related to a Store, and getting the users, addresses and what not, JPA forces you to create a Store Entity that contains all these things.

StoreBond {
       List<Address> address
       List<User> users
       ....
}

My intention is just to user this for query, never to insert so I don't need a table for it.

My intention is to be able to build Hibernate criteria queries and map the associations to do so. Criteria queries can be quite powerful to filter on things.

But I do not want an empty table in my sql schema since it won't do anything anyway, I also don't want this class to have anything to do with the model other than mapping to it results from the database.

Is there a way around this limitation.

To have a connection/bond entity merely for getting to the associations to be able to query them and binding the result to this object.

The alternative is that I have declared StoreBond { .. } class as the center of everything, which I find problematic over time.

Embeddable is problematic syntactically so I please do not entertain it for this purpose.

Not, sure what happens if you map such a StoreBond entity currently and then immediately after schema generation drop it from the database. I think that might still work on the JPA level, but not sure. It might be required to have certain ids populated which would be the basis for reaching out to the other associations?

Rob
  • 14,746
  • 28
  • 47
  • 65
mjs
  • 21,431
  • 31
  • 118
  • 200
  • I don't follow you, but maybe it is because of your naming. What is StoreBond and why does it exist? Store->User is a ManyToMany or a OneToMany (where user then has a ManyToOne->Store)? JPA does not force you to do anything, your use case is the one forcing you to have some container that can hold Store references. Why would there be a problem with a Store entity having references? It is a common practice, and while there are pitfalls with references, they have well documented solutions. – Chris Feb 22 '23 at 16:22
  • Otherwise, you can easily have a StoreLight (for basic mappings) and Store entity with references (Both just need the Table annotation that tells JPA that they use the same table), or just use view objects or fetch graphs to only return the basic mappings on the Store entity. As for querying, if User has a reference to Store, you don't need a reference from Store to user to be able to query over that relationship. – Chris Feb 22 '23 at 16:24
  • Hmm... what I want and have are Store things, defined as own entities, because I have not found it historically stable or maintainable enough to have one big store entity containing all the stuff related to it. Rather, if I need to add something to Store, such as StoreCustomer, I create a new entity and thus a new table with that relationship alone. However, doing it this way, you no longer have a central Store entity, from which you can a) search, b) collect related data easily. – mjs Feb 24 '23 at 12:42
  • Now, there should be a way to create a Store entity that only exists in theory, or as a mapper object which will allow you this, which we could call StoreBond. It would be only a read entity, and for the purpose of querying and building say hibernate criteria queries. The other relationships already exists, so it would be a question of how to map existing tables onto this readonly lesser "entity". I do not need a table for it but that I can manage do myself. – mjs Feb 24 '23 at 12:46
  • Not sure what you mean at all - Other than the need for a customers table (and possibly ManyToMany join table) what new or other table is involved? If you have a Store entity, adding a reference to a list of customers seems trivial. You can clear up what you mean by showing it in your question, but yes, you can map an entity to a table, any table, just to read from them. Caching that data becomes a pain - if you've already loaded that same partial data as 'storeX' querying and fetching 'StoreY' can't use any of it and will have to fetch it again. – Chris Feb 24 '23 at 15:40
  • Why not just create the uber Store entity that models the database as it really is. If your issues are with passing around that instance, that is what DTOs and mappers are for - use your trimmed down view objects to convert Store instances into StoreCustomerDTO with only the data needed. Leave everything as lazily fetched and you won't see much difference (though fetch joins might help on some relationships if you know they'll be needed for some DTOs but not others). Projections (answered above) is common in Spring for the same thing, as is JPA constructor queries to build non-entities – Chris Feb 24 '23 at 15:42
  • The uber entity is exactly what I am trying to avoid. JoinTable seems to have done the trick for now. – mjs Feb 24 '23 at 16:58

1 Answers1

0

To query without the need of an entity can be solved using projections. A very good answer provided by Vlad Mihalcea on stackoverflow - 23719237.

Instead of an entity to aggregate store data, you can a DTO to store the data fetched.

In your case, you would still have a class like StoreBond, but as a simple DTO instead of an entity.

However your question is quite challenging in itself because I do no think it is possible to all the data at once or even with the help of a "third" table.

The "third" table would be looking like;

store id       user id      address id
1               1           null
1               2           null
1               null        1
1               null        2

If there is a native query to fetch all the data at once, it can easily be translated to JPQL and used with the JPA's EntityManager.

atish.s
  • 1,534
  • 11
  • 19