Java Hibernate Annotation(@JoinTable,@ Filter)

时间:2012-07-13 18:13:18

标签: java sql hibernate annotations jointable

我最近开始使用Hibernate,并试图了解所有注释并确保我正确地做事。我有两个表'user'和'user_friends',类似于下面的

+------+------+-------+------+
| id   | name | email | etc. |
+------+------+-------+------+

和用户朋友表

+--------+---------+----------+
| userid | buddyid | accepted |
+--------+---------+----------+

现在在SQL中我运行了一个类似于

的查询
SELECT u.id AS id, u.name AS username, u.email AS email FROM user_friends 
INNER JOIN users AS u ON u.id = '1' WHERE buddyid = '2' AND ACCEPTED = 1 UNION ALL 
SELECT u.id as id, u.name AS username, u.email AS email FROM user_friends
INNER JOIN users AS u ON u.id = '2' WHERE buddyid = '1' AND ACCEPTED = 1;

我在Java设置中有两个类似于

的方式
@Entity
@Table(name="users")
public class User {

  @Id
  @GeneratedValue
  private int id;

  private int name;
  private int email;

  private DateTime registerDate;
  private DateTime lastActivity;

  private int currency;
  private int seasonCurrency;

  @OneToMany(fetch=UserBuddy.class, mappedBy="user", fetch=FetchType.LAZY)
  @JoinColumn(name="userid")
  @Filter(name="messengerBuddyFilter", condition="accepted=1")
  private Set<UserBuddy> _buddies;
}

@Entity
@Table(name="user_friends")
public class UserBuddy {

   private int id;
   private int name;
   private int email;
}

之前我问过这个问题,但仍然无法按照我的意愿开展工作。我需要能够返回一组UserBuddy.class,其中包含该Buddy的名称和电子邮件,而不是其他注册时间等(通过使用User类进行映射)。我也很难确保它只返回已接受请求的伙伴(ACCEPTED = 1)

任何人都可以提供任何建议吗?

1 个答案:

答案 0 :(得分:1)

如果您正在使用JPA(以及使用hibernate和JPA命名的本机查询有问题)或IIRC sql查询(如果只使用纯hibernate),则需要使用本机查询。

这可能有用......只是快速做到这一点,将它作为一个起点。假设您在JPA中有一个名为em的实体管理器,它被定义为类成员变量

@PersistenceContext(unitName = "MyPersistenceUnit_PU")
private EntityManager em;

...

某种方法......

List<UserBudy> buddyList = new <>ArrayList();
Query q = createNativeQuery("SELECT u.id AS id, u.name AS username, u.email AS email "
                          + "FROM user_friends "
                          + "INNER JOIN users AS u "
                          + "ON u.id = '1' "
                          + "WHERE buddyid = '2' "
                          + "AND ACCEPTED = 1 "
                          + "UNION ALL "
                          + "SELECT u.id as id, u.name AS username, u.email AS email "
                          + "FROM user_friends "
                          + "INNER JOIN users AS u "
                          + "ON u.id = '2' "
                          + "WHERE buddyid = '1' "
                          + "AND ACCEPTED = 1");
List<UserBudy> buddyList = (List<UserBudy>)em.getResultList);

此示例不是“命名”本机查询。这是类似于POJDBC(普通旧jdbc)内联完成的。就像我说的,如果你打算尝试使用JPA和Hibernate创建一个NamedNativeQuery,你会得到一个“某些东西或其他未实现的异常”。 Hibernate永远不支持使用JPA的命名本机查询。它仍然在他们的错误跟踪器的某个地方(已经有5年或6年),看起来他们没有给老鼠屁股修理它。总的来说,在使用PostgreSQL时,与使用Eclipselink相比,Hibernate的问题较少,所以我现在可以忍受它。 :)

如果您使用纯hibernate执行此操作,那么您将创建一个Hibernate会话对象而不是JPA EM对象,而是使用createSQLQuery。除此之外几乎是一样的。

session.createSQLQuery("...");

如果这没有足够的帮助,你现在应该至少有足够的信息来解决它。

如果你想在使用纯JPA之后尝试一下,这里有一个链接。在本文的中间部分查找“订单项摘要”示例。

http://www.oracle.com/technetwork/articles/vasiliev-jpql-087123.html

请记住,当您处理JPA时,您正在加入实体,而不是表格。无论如何,那篇文章是我发现的最清楚的文章之一,展示了它的很多功能。问候。