我正在为java开发一个带有游戏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;
...
在我的控制器中,我有一个函数,它将图片byte[]
写入DeviceModel
对象并调用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)
,但它没有解决问题。
任何想法为什么会这样?
答案 0 :(得分:2)
我找到了解决此问题的方法,但我仍然想知道原因,为什么直接访问图片字段,返回null。
这是解决方法:
我只是将我的picture
字段设为私有,并使我自己得到了吸气剂。现在在我的控制器中,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;
}
...
答案 1 :(得分:0)
该行为的原因是FetchType.LAZY
(显然也是Lobs的默认值)。它告诉Ebean懒惰地获取数据,即不是在加载对象时立即获取数据,而是仅在您实际访问它时。
由于Ebean在您直接前往该字段(picture
)时无法检测到访问权限,因此根本不会发生加载,您将获得null
。
通过使用getPicture()
,其代码由Ebean 增强,它知道在返回值之前加载数据。
只需使用FetchType.EAGER
,您就可以克服这种行为。但是你应该这样做,如果你确定你总是需要数据,因为它需要更多的时间和内存(例如在你的例子中,如果你有100张图片而你只想显示一个名单列表,它会没有必要加载所有图片的实际图像数据。