Lob returns null 使用 play framework 和 Ebean 和 H2

Lob returns null using play framework and Ebean and H2

我正在为 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),但并没有解决问题。

知道为什么会这样吗?

我找到了解决此问题的方法,但我仍然想知道原因,为什么要直接访问图片字段,returns 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;
}

...

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

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

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

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