Select subset of the list contained in an entity

爷,独闯天下 提交于 2019-12-13 06:02:17

问题


Say I want to get all rows of the MyEntity that have an id lower than 10. This entity contains a list of Another entity. I would like this list to be fetched only by a subset of the listAnother. This subset containing only Another where the user contained in it is a specific one.

Basically in SQL it would be like this :

SELECT * FROM myentity m
LEFT JOIN another a
ON m.idTable=a.my_entity
AND a.user = "test1"
WHERE m.idTable < 10;

I didn't manage however to translate this query to jpql.

My entities being like this :

@Entity
public class MyEntity implements Serializable {    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idTable;

    @OneToMany(mappedBy = "myEntity")
    private List<Another> listAnother;

}

@Entity
public class Another implements Serializable {    
    @Id
    private int idAnother;

    // bi-directional many-to-one association to Thethread
    @ManyToOne(fetch = FetchType.LAZY)
    private MyEntity myEntity;

    @ManyToOne(fetch = FetchType.LAZY)
    private User user;
}

@Entity
public class User implements Serializable {

    @Id
    private String username;
}

In jpa I could do this :

SELECT m FROM MyEntity where m.idTable < 10;

And then for each entity I get from this list call this:

SELECT a FROM Another Where a.user.username=:'test' AND a.myEntity=:entity;

However I would like to do it all at once in one query. Can I do this with criteria ? I didn't take the time to learn it but if it's possible then I will.


回答1:


JPQL and Critaria API are equal in terms of what you can express with them. What is possible with JPQL is possible with Criteria and vice versa.

With JPQL, you can simply combine your 2 queries into one in this way:

SELECT a FROM Another a Where a.user.username=:test AND a.myEntity.idTable < 10

You can use dot notation (.) to join multiple entities in the query, provided that the relationship is X-to-one. If you have X-to-many relationship, you need to use JPQL JOIN, which is not very complicated. Example with (LEFT) JOIN:

SELECT m FROM MyEntity m LEFT JOIN m.listAnother a Where a.user.username=:test AND m.idTable < 10

The result is of course not equal - in first case you will get list of Another entities and you can get MyEntity by a.myEntity, in the second case you will get list of MyEntity, which all have at least one Another entity with given user




回答2:


In hibernate you can use Filters and FilterJoinTable. Here you can read how to do that. Similar problem was solved here.




回答3:


You need to extend the logic which you applied to check the username (a.user.username=:'test') which was for many-to-one relation between anything and user by taking it one level up to myEntity and then using it for one-to-many relation as well -

 SELECT m FROM MyEntity where m.idTable < 10 and (m.listAnother.user.username=:'test')

The join condition "m.listAnother.myEntity=:entity" wouldn't be needed now as in our query we have started from the specific myEntity and then moved down to listAnother.user.username .

I don't have the table definitions to try this query myself, exact SQL may require some tweaks - but logically it should work like the way I showed above, i.e. just the way you joined Another with User, the same way you can join MyEntity with Another by just traversing down the child listAnother.



来源:https://stackoverflow.com/questions/32684341/select-subset-of-the-list-contained-in-an-entity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!