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 多张图片并且你只想显示一个名字列表,它会也不需要加载所有图片的实际图像数据。
我正在为 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 多张图片并且你只想显示一个名字列表,它会也不需要加载所有图片的实际图像数据。