简体   繁体   中英

Custom hibernate criteria (one-to-many relationship)

I need to create custom Hibernate query.

    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<User> criteria = builder.createQuery(User.class);
    Root<User> user = criteria.from(User.class);
    List<Predicate> restrictions = new ArrayList<>();
    restrictions.add(builder.equal(user.get("firstname"), user.getFirstName()));
    List<User> users = (List<User>) entityManager.createQuery(criteria).getResultList();

I need to add to restrictions additional criteria. I have additional model Photo , which connected to model User with foreign key user_id . I need to find users, which has any photos.

User model contains:

 private List<Photo> photos;

 @OneToMany(fetch = FetchType.LAZY, mappedBy = "photo", cascade = CascadeType.ALL)
 @Fetch (FetchMode.SELECT)
 @JsonIgnore
 public List<Photo> getPhotos() {
     return photos;
 }

Photo model contains:

private User user;

@ManyToOne
@JoinColumn(name="user_id")
public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

UPDATED

I need something like this:

restrictions.add(builder.isNotNull(user.get("photos")));

but it's not working.

Problem is not with how to combine 2 restrictions, problem with how to add restriction isNotNull... User know nothing about photos. Photos know about user as they has user_id.

UPDATED2 :

org.postgresql.util.PSQLException: ERROR: syntax error at or near "."

SQL:

select * from User user0_ cross join Photo photos1_ where user0_.id=photos1_.user and (. is not null)

I need follow SQL:

 SELECT DISTINCT user.* FROM user
 LEFT JOIN photo
 ON user.id = photo.user_id;

Try this:

restrictions.add(Restrictions.and(Restrictions.eq(user.get("firstname"), user.getFirstName()),Restrictions.isNotNull(user.get("photos")));

UPDATE: The bidirectional relationship you are looking for is something like this:

Photo class:

@ManyToOne
@JoinColumn(name="user")
private User user;

User class:

@OneToMany(mappedBy="user")
private Set<Photo> photos;

In this one you have it mapped both ways so you can access photos from the user and user from photos.

I found solution myself. Full code:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> user = criteria.from(User.class);
Root<Photo> photo = criteria.from(Photo.class);
List<Predicate> restrictions = new ArrayList<>();
restrictions.add(builder.equal(user.get("firstname"), user.getFirstName()));
restrictions.add(builder.equal(user.get("id"), photo.get("user")));

List<User> users = (List<User>) entityManager.createQuery(criteria).getResultList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM