- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个 Song 类,其中包含一组 CoverArt
例如
@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
@JoinColumn(name = "recNo")
private List<CoverArt> coverArts;
我正在使用 Hibernate 4.3.11 和 DB2 数据库,我有这个查询来通过主键和封面艺术检索歌曲列表。
public static List<Song> getSongsWithCoverArtFromDatabase(Session session, List<Integer> ids)
{
try
{
Criteria c = session
.createCriteria(Song.class)
.setFetchMode("coverArts", FetchMode.JOIN)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.add(Restrictions.in("recNo", ids));
List<Song> songs = c.list();
return songs;
}
catch (Exception e)
{
MainWindow.logger.log(Level.SEVERE, "Failed LoadSongToDatabase:" + e.getMessage(), e);
throw new RuntimeException(e);
}
}
请注意,我们已将 coverArts 集合的获取模式设置为 JOIN,并且我们需要设置 setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) ,否则如果我们有一首包含两个翻唱唱片的歌曲,我们将返回两个 Song 对象。但是当使用 Criteria.DISTINCT_ROOT_ENTITY 时,Hibernate 会正确地返回一首包含两个封面艺术的歌曲。
然而,我刚刚尝试做同样的事情,但使用的是 StatelessSession。原因是我只是想选择数据来创建报告,但我想最大化速度并最小化内存消耗
public static List<Song> getSongsWithCoverArtFromDatabase(StatelessSession session, List<Integer> ids)
{
try
{
Criteria c = session
.createCriteria(Song.class)
.setFetchMode("coverArts", FetchMode.JOIN)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.add(Restrictions.in("recNo", ids));
List<Song> songs = c.list();
return songs;
}
catch (Exception e)
{
MainWindow.logger.log(Level.SEVERE, "Failed LoadSongToDatabase:" + e.getMessage(), e);
throw new RuntimeException(e);
}
}
这似乎忽略了 .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 并返回重复行。
这是一个已知的错误吗?它的行为方式是什么?
最佳答案
看起来这是 StatelessSessionImpl
在 Hibernate 中实现的方式的缺点,但修复可能也在路上......
很明显,对于 FetchMode.JOIN
,SQL 查询将(左外)连接两个表,因此每首歌曲可能返回多行。通常,Hibernate 解析通过其 PersistenceContext
返回的每一行。
如果有兴趣,您可以在 Loader
的 Hibernate 源代码中看到这个 here .然后,根据 Session
的类型,SessionImpl.getEntityUsingInterceptor()与 PersistenceContext
对话,但是 StatelessSessionImpl.getEntityUsingInterceptor()只返回空值。但是有一个 later commit这种看起来做正确事情的方法。提交是 HHH-11147 的一部分,它表示修复版本是 Hibernate 5.3.11 和 5.4.4 - 未显示在 Maven repo 中在撰写本文时。
与此同时,一种解决方法是推出您自己的 ResultTransformer
。这是一个相当“切题”的例子:
public class DistinctSongResultTransformer implements ResultTransformer {
private ResultTransformer defaultTransformer = Criteria.DISTINCT_ROOT_ENTITY;
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return defaultTransformer.transformTuple(tuple, aliases);
}
@SuppressWarnings("rawtypes")
@Override
public List transformList(List collection) {
Map<Integer, Song> distinctSongs = new LinkedHashMap<>();
for (Object object : collection) {
Song song = (Song) object;
distinctSongs.putIfAbsent(song.getId(), song);
}
return new ArrayList<>(distinctSongs.values());
}
}
区别在于普通的 DistinctRootEntityResultTransformer
假定 session 中只有一个唯一的实体实例 - 你可以看到比较 here .
显然,还有使该示例更具可重用性的空间,特别是抽象 getId()
。
关于java - 在 Hibernate 中,StatelessSession 在有 EAGER JOIN 时防止过滤掉重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56528721/
显然,可以实现 Haskell,使其在不改变语言语义的情况下急切地求值。如果这是真的,如何处理无限数据结构? http://csg.csail.mit.edu/pubs/haskell.html Th
有没有什么方法可以像@ManagedBean(eager=true ) 来自 javax.faces 包? @Named @ApplicationScoped public Mail() { ...
使用@ApplicationScoped @Named @Eager,我的@EJB注入(inject)的@Stateless bean未正确实例化并评估为空。 我有一个@ApplicationScop
我必须删除两个分隔符之间的字符串,即 从“123XabcX321”我想要“123321”。 对于一个简单的案例,我很好: $_=<>; s/X(.*)X//; print; 但是,如果像“123Xab
我有一个对象层次结构,订单,联系人,地址: public class Order { public virtual Contact BillingContact { get; set; }
Eager 模式仅支持 TF native 优化器我在以下尝试过的每个优化器中都会遇到此错误: def create_model(): model = tf.keras.models.Sequ
我有这样的数据设计:交易属于授权,而授权又属于客户。或者用结构体表示: type Transaction struct { shared.Transaction // transaction
我想在 Scheme 中做一个懒惰的列表。这是我到目前为止。 ;; Constructor for Pairs (define (cons-stream a b) (cons a (λ() b))
今天是个好日子 我是 Laravel 的新手,目前正在用它构建我的第一个简单的新闻应用程序 我有一个简单的查询,使用 laravel 的预先加载功能 但是在这个急切的加载功能中,我想根据某些条件获取某
我正在制作一个动态表单,让用户使用 vue.js 自动生成带有游戏统计信息的图像,并使用 Keen-ui。我是 vue.js 的新手,过去两周开始学习它。 现在,我在使用 eager-ui 进行选择下
我 fork 了 eager/dashboards github 存储库,并尝试创建一个 Dockerfile 以在 Docker 容器中运行仪表板。 我的 fork :https://github.
我的实体: @Entity @NoArgsConstructor public class Company { @Id @Getter @GeneratedValue(strategy =
在我的实体中,我必须使用 fetch = FetchType.EAGER 因为我有一个错误: nested exception is org.hibernate.LazyInitializationE
我在 Java 中使用 play 2.0.4。我正在尝试从 play 提供的内存数据库中保存和检索值(Ebean 是底层 JPA 实现)。下面是一些示例代码: @NoobDisclaimer ("I'
在 Pro .NET Performance - Optimize Your C# Applications 的第 96 页上,它谈到了 GC 急切根收集: For each local variab
我无法从数据库加载对象及其相对映射对象。可能我的“ map 系统”是错误的。 在数据库中保存对象(及其相对映射对象)时,一切正常,因此对象似乎已正确映射。 Utente是我的“主”对象 publ
我需要使用急切查询在 Laravel 中执行子查询,但结果始终为空。 查询: $project = Log::where('project_id', $id)->with(['log_occurenc
我有这个程序: var planetStream = require('../../'); var app = require('http').createServer(handler); var i
我需要与FetchType.EAGER(下面的示例)建立关系,但我有异常(exception)。如果我将 FetchType.EAGER 更改为 FetchType.LAZY 一切正常,但我确实需要
我正在使用 EF6 并尝试急切获取对象的整个结构。问题是我正在使用继承。 假设我有这个类(class)。 数据库上下文 DbSet A { get; set; } 示例类 public class A
我是一名优秀的程序员,十分优秀!