【发布时间】:2017-03-28 09:26:07
【问题描述】:
我有一个带有 hibernate 的 Web 应用程序,它可以管理多种语言的数据。目前基本上每个请求都会生成大量关于语言翻译的选择语句。模型大致如下:
Data <1-1> Placeholder <1-many> languageTranslation <many-1> language
如果我查询所有/许多数据对象,我会看到许多单选,它们为占位符选择一种语言翻译。我最想生成的 SQL:
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,但无法生成我想要的行为,它总是单选单语言翻译。
我还尝试了多种查询方式,包括基于条件的、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 在一个数据库调用中获取所有实体?或者在我的情况下是否有其他方法可以提高性能(例如批量选择)?
【问题讨论】:
-
“在一个数据库调用中获取所有实体”是什么意思?您能否手动模拟您希望收到的查询类型以及您认为应该如何将其转换为对象模型?
-
@Andremoniy 我想要所有带有初始化
data.content和初始化data.content.languageTranslations的数据对象。所以基本上我想要我展示的 SQL,但休眠知道我已经为它加载了所有占位符和 LanguageTranslations,它不需要再查询它了。