Hibernate JPA查询多个连接表

时间:2017-01-16 20:32:00

标签: java postgresql hibernate jpa

我无法理解一件事。

这是测试DDL:

CREATE TABLE public.role
(
    id   SERIAL PRIMARY KEY
);

CREATE TABLE public.role_translate
(
  id SERIAL PRIMARY KEY,
  name VARCHAR(30),
  roleId INT REFERENCES public.role(id),
  locale VARCHAR(2)
);

CREATE TABLE public.users
(
    uuid UUID PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL
    uuid UUID PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL
  , username VARCHAR(45) UNIQUE
  , email VARCHAR(255) UNIQUE
);

CREATE TABLE public.user_role
(
    uuid     UUID PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL
  , userUuid UUID REFERENCES public.users(uuid) NOT NULL
  , roleId INT REFERENCES public.role(id) NOT NULL
);

好。现在我给你看POJO课程。

用户类

@Entity
@Table(name = "users", catalog = "catalog", schema = "public")
public class User implements Serializable {

    private static final long serialVersionUID = 1325687088267757690L;

    @Id
    @GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY)
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Column(name = "uuid", unique = true)
    private UUID uuid;

    @Column(name = "username")
    private String username;

    //....
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private Collection<UserRole> userRoles = new HashSet<>();
}

UserRole类

@Entity
@Table(name = "users", catalog = "catalog", schema = "public")
public class UserRole {

    private static final long serialVersionUID = 1935684358277757690L;

    @Id
    @GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY)
    @GenericGenerator(name = "system-uuid", strategy = "uuid2")
    @Column(name = "uuid", unique = true)
    private UUID uuid;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE})
    private User user;

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE})
    private Role role;
}

角色等级

@Entity
@Table(name = "role", catalog = "catalog", schema = "public")
public class Role implements Serializable {

    private static final long serialVersionUID = 2874365798237423123L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "roles_seq_gen")
    @SequenceGenerator(name = "roles_seq_gen", sequenceName = "roles_id_seq")
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "role", cascade = CascadeType.ALL)
    private List<RoleTranslate> roleTranslateList;

    //...
}

因此,用户可以扮演很多角色。

现在我想得到这个 - 我想通过用户名字段和角色找到用户,但我必须通过语言环境找到角色。

这个SQL做我想要的:

SELECT * FROM user_role UR 
  JOIN role R ON R.id = UR.roleid 
  JOIN role_translate RT ON RT.roleid = R.id 
  JOIN USERS U ON U.uuid = UR.useruuid 
WHERE U.username = 'username' AND RT.LOCALE = 'de';

这是我试过的:

    EntityManager em = sessionFactory.createEntityManager();
    em.createQuery("select r from User u " +
            "join fetch u.userRoles ur " +
            "join fetch ur.role r " +
            "join fetch r.roleTranslateList rt " +
            "where u.username = :username AND rt.locale = 'de'", User.class)
            .setParameter("username", username)
            .getSingleResult();
    em.createQuery(
            "select u " +
                    "from User u " +
                    "inner join fetch u.userRoles ur " +
                    "inner join fetch ur.role r " +
                    "inner join fetch r.roleTranslateList rt " +
                    "where u.username = :username AND rt.locale = 'de'", User.class)
            .setParameter("username", username)
            .getResultList();

但我无法理解如何使用JPA机制实现这一点。我的所有变种都给了我NPE或其他东西。我想要使​​用User类返回Collection<UserRole> userRoles类的实现方法,其中将存在UserRole类对象的列表,其中类Role将只翻译de区域设置平移。

0 个答案:

没有答案