Question

I have the following model;

  • I have users and rules and teams
  • a user can be added to 0, 1 or more rules
  • a user can be added to 0, 1 or more teams
  • a rule can be added to one team only, but a team can contain many distinct rules
  • a rule can contain 0, 1 or more users

Here is the UserEntity class:

    class UserEntity {

    private String username;

    private List<TeamEntity> teams;

    private List<RuleEntity> rules;

    @Column(name = "username", nullable = false, unique = true)
    public String getUsername() {
        return username;
    }

    @ManyToMany(mappedBy="users" , fetch = FetchType.LAZY)
    public List<RuleEntity> getRules() {
        return rules;
    }

    @ManyToMany(mappedBy="users" , fetch = FetchType.LAZY)
    public List<TeamEntity> getTeams() {
        return teams;
    }

    ...
}

And the RuleEntity class:

    class RuleEntity {
        private String name;

        private List<UserEntity> users;

        private TeamEntity ownerTeam;

        @Column(name = "name", nullable = false)
        public String getRuleName() {
             return ruleName;
        }

        @ManyToOne 
        @JoinColumn(name=TeamEntity.TEAM_ID, nullable = false)
        public TeamEntity getOwnerTeam() {
            return ownerTeam;
        }

        @ManyToMany (fetch = FetchType.LAZY)
        @JoinTable(name= "RULE_USER" ,joinColumns=@JoinColumn
        (name=RuleEntity.RULE_ID, referencedColumnName="ID", insertable = true, updatable = false, nullable = false),
      inverseJoinColumns=@JoinColumn
      (name=UserEntity.USER_ID, referencedColumnName="ID", insertable = true, updatable = false, nullable = false), 
      uniqueConstraints = @UniqueConstraint(columnNames = {RuleEntity.RULE_ID, UserEntity.USER_ID}))
      public List<UserEntity> getUsers() {
         return users;
      }

      ...
  }

And the TeamEntity class:

class TeamEntity {

        private String name

        private List<UserEntity> users;

        private List<RuleEntity> rules;

       @ManyToMany (fetch = FetchType.LAZY)
       @JoinTable(name= TeamEntity.TEAM_USER_TABLE,joinColumns=@JoinColumn(name=TeamEntity.TEAM_ID, referencedColumnName="ID",
      insertable = true, updatable = false, nullable = false),
      inverseJoinColumns=@JoinColumn(name=TeamEntity.USER_ID, referencedColumnName="ID",
      insertable = true, updatable = false, nullable = false),
      uniqueConstraints = @UniqueConstraint(columnNames = {TeamEntity.TEAM_ID, TeamEntity.USER_ID}))
      public List<UserEntity> getUsers() {
          return users;
      }

      @OneToMany (mappedBy = "ownerTeam", cascade = {CascadeType.ALL}, orphanRemoval=true)
      public List<RuleEntity> getRules() {
          return rules;
      }
      ...
    }

So, given I have the following model created:

 /**
 * <pre>
 *                 Team ("team1")
 *                       |
 *                  Rule ("rule1")
 *                       |            |
 *                   User ("john")
 * </pre>
 */

 /**
 * <pre>
 *              Team ("team4")
 *                    |          
 *              Team ("team5")
 *               |           |
 *     Rule ("rule4")       Rule ("rule5")
 *                          |            |
 *                User ("paul")        User("john")
 * </pre>
 */

I am trying to implement a search whereby a user can search using a username, a team name and a rule name, i..e so the 3 have to match in order to return any results. I currently have the following to return users matching the 3 search terms:

select distinct users from UserEntity as users inner join users.rules as rules inner join users.teams as teams where users.username like :john and rules.ruleName like :rule1 and teams.name like :team5

So using the HQL query above, I would expect the result to return no user entities (because there is no team5 with a rule1 in it, where the rule1 has john in it), but instead it is returning 'John'

Does anyone know how to tweak the above query so that it works as I've described (i.e. it should only return a result when all 3 match)?

Was it helpful?

Solution

Ok these are my thoughts on this:

You have 3 tables: users, rules and teams. The first table contains paul and john. The second table contains rule1,rule4, rule 5.

The join of these tables return john - rule1; john - rule5; (JOIN1)

The third table contains team1, team4 and team 5. Now you join users with this table. You get john-team1; john-team 5.(JOIN2)

Now you are asking is there a john in USERS (yes) with rule1 in JOIN1(yes) and team5 in JOIN2(yes). There you go.

What you need to do is to join the teams with the rules.

select distinct users from UserEntity as users inner join users.teams as teams inner join user.rules as rules1 inner join teams.rules as rules2
where users.username like :john and rules1.ruleName like :rule1 and rules2.ruleName like :rule1 and teams.name like :team5.

But it's pretty strange to have rules both in Users and Teams. I would reconsider this.

OTHER TIPS

  1. "a user can be added to 0, 1 or more rules" is a @ManyToOne(nullable=true) NOT @ManyToMany
  2. select distinct [someCollection] does not make sense (it needs to be select distinct [someEntity])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top