Lob 使用 play 框架和 Ebean 和 H2 返回 null

Posted

技术标签:

【中文标题】Lob 使用 play 框架和 Ebean 和 H2 返回 null【英文标题】:Lob returns null using play framework and Ebean and H2 【发布时间】:2015-06-11 10:49:19 【问题描述】:

我正在为 java 开发一个带有 play 2.3(带有 Ebean 和 H2)的程序。我有一个这样的模型:

@Entity
public class DeviceModel extends Model implements PathBindable<DeviceModel> 

@Id
public Long id;


@Lob
@Basic(fetch=FetchType.LAZY)
public byte[] picture;

...

在我的控制器中,我有一个函数,它在DeviceModel 对象内将图片写为byte[] 并调用update() 函数。所以现在应该将图片保存在数据库中。

我有这个功能来显示图片:

public static Result picture(Long id) 
    final DeviceModel deviceModel = DeviceModel.findByID(id);
    if (deviceModel == null)
        return notFound();
    
    return ok(deviceModel.picture);

有趣的是deviceModel.picture 为空!

但在我看来,我有这个:

        @if(deviceModel.picture != null) 
                show the picture!
         else
            do something else
        

但是在这里,deviceModel.picture 不为空!!!大多数情况下,图片都会正确显示!!

我删除了@Basic(fetch=FetchType.LAZY),但并没有解决问题。

任何想法为什么会这样?

【问题讨论】:

只是猜测:您的模板实际上是使用 getPicture() 方法而不是直接访问该字段。也许你在这个方法中有一些额外的代码以某种方式转换图片的字节[]? 感谢您的提示。作为一种解决方案,我将我的图片字段设为私有,并设置了我自己的 getter 和 setter。现在用 getPicture() 我总是能得到数据 【参考方案1】:

我找到了解决此问题的方法,但我仍然想知道原因,为什么直接访问图片字段返回 null。

解决方法如下: 我刚刚将我的 picture 字段设为私有,并让我的自己成为了 getter 和 setter。现在在我的控制器中,getPicture() 我总是能得到数据

@Entity
public class DeviceModel extends Model implements PathBindable<DeviceModel> 

@Id
public Long id;


@Lob
@Basic(fetch=FetchType.LAZY)
private byte[] picture;


public byte[] getPicture() 
    return picture;


public void setPicture(byte[] picture) 
    this.picture = picture;


...

【讨论】:

【参考方案2】:

这种行为的原因是FetchType.LAZY(这显然也是 Lobs 的默认值)。它告诉 Ebean 延迟获取数据,即不是在您加载对象时立即获取数据,而是仅在您实际访问它时。

当您直接前往现场 (picture) 时,由于 Ebean 无法检测到访问,因此根本不会发生加载,您会得到 null

通过使用getPicture(),其代码被Ebean增强,它知道在返回值之前加载数据。

您可以通过简单地使用FetchType.EAGER来克服这种行为。但是你应该只这样做,如果你确定你总是需要数据,因为它需要更多的时间和内存(例如,在你的例子中,如果你有 100 张图片并且你只想显示一个名称列表,它会也不必加载所有图片的实际图像数据。

【讨论】:

这对我来说完全是正确的解决方案,因为@behzad 解决方案不起作用

以上是关于Lob 使用 play 框架和 Ebean 和 H2 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

我不能在游戏框架中使用 ebean

Ebean和Play!不使用.select()过滤列

玩!框架+Ebean

Java Play 中的配置 - ebean 和 postgresql

获取使用 Ebean 在 Play Framework 中保存的最新更新行

数据库“默认”需要进化!尝试使用 play framework 2.7.0 和 Ebean 连接到 MySQL 时