在hibernate中有效地从数据库加载集合集合

时间:2017-03-28 09:26:08

标签: java hibernate

我有一个带有hibernate的web应用程序,可以管理多种语言的数据。目前,基本上每个请求都会在语言翻译上产生一系列精选语句。模型大致如下:

Data <1-1> Placeholder <1-many> languageTranslation <many-1> language

如果我查询所有/多个Dataobjects,我会看到很多单选项,为占位符选择一个languageTranslation。 SQL I最想要生成:

SELECT * FROM data join placeholder join languagetranslation 
WHERE data.placeholder_id = placeholder.id 
AND languagetranslation.placeholder_id = placeholder.id 
AND languagetranslation.language_id = ?

这样我就可以通过一次调用获得带有翻译的占位符的每个数据。语言翻译具有language_id和placeholder_id的复合主键。

我没有HBM文件,所有内容都使用注释进行管理。模型代码(仅显示相关部分):

@Entity
public class Data {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, optional = false)
    @Fetch(FetchMode.JOIN)
    private Placeholder content;
}

public class Placeholder { 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "primaryKey.placeholder", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @Fetch(FetchMode.JOIN)
    private Set<LanguageTranslation> languageTranslations = new HashSet<>();
}

public class LanguageTranslation {

    @EmbeddedId
    private LanguageTranslationPK primaryKey = new LanguageTranslationPK();

    @Type(type = "org.hibernate.type.StringClobType")
    private String text;

}

@Embeddable
public class LanguageTranslationPK {

    @ManyToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private TextPlaceholder textPlaceholder;

    @ManyToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private Language language;
}

public class Language {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

我尝试了FetchType和FetchMode但是无法生成我想要的行为,它总是单个选择单个languageTranslations。

我还尝试了多种查询方式,基于标准,HQL和原始SQL。我当前的原始SQL查询如下:

String sql_query = "select data.*, lt.* from Data as data join languagetranslation as lt on data.content_id = lt.textplaceholder_id";
Query q = getSession().createSQLQuery(sql_query).addEntity("data", Data.class).addJoin("data.content_id", "data.title").addJoin("lt", "data.content.languageTranslations").setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return q.list();

我在这里做错了吗?我怎样才能说服hibernate在一个数据库调用中获取所有实体?或者是否有其他一些方法可以改善我的情况(例如批量选择)?

2 个答案:

答案 0 :(得分:1)

您可以使用getter setter和constructor创建具有所有实体变量的代理pojo。然后在hibernate查询中初始化这个构造函数,这样你就可以从数据库中获取所有需要的数据。

import com.proxy;
 class userProxy{
private string name;
private string password;
private string address;
private int pincode;
private byte[] profilePic;
private int age;

public userProxy(string name,string password){
  this.name = name;
  this.password = password;
}

//Getter and setter of all variable...
}

然后使用此构造函数进行Hibernate查询,如

select new com.proxy.userProxy(user.name,user.password) from usertable

答案 1 :(得分:0)

  

我在这里做错了吗?

不,你不是。这就是Hibernate的工作原理。

  

如何说服hibernate在一次数据库调用中获取所有实体

您必须使用HQL或SQL查询来执行此操作。您不需要拥有HBM文件。可以使用list方法通过@NamedQueries / @NamedQuery注释来完成。

互联网上有很多样本,例如简单的样本:

http://www.mkyong.com/hibernate/hibernate-named-query-examples/