【发布时间】:2019-07-18 08:10:49
【问题描述】:
我有这两个实体:
@Entity
@Immutable
@Cacheable
@Cache(region = "dosefrequency", usage = CacheConcurrencyStrategy.READ_ONLY)
public class DoseFrequency{
.....
}
@Entity
public class PrescriptionDrug {
.....
@ManyToOne(optional=false)
@JoinColumn(name="doseFrequency")
public DoseFrequency getDoseFrequency() {
return doseFrequency;
}
}
DoseFrequency 是一个只读实体,PrescriptionDrug 关联了一个 DoseFreqyency。我希望每次加载一个或多个 PrescriptionDrug 时都不会重复 DoseFrequency 的实例。
我知道 DoseFrequency 实例将被缓存在 hibernate 的一级缓存中,但加载是在几个会话中完成的(它是一个 web 应用程序)。我用的是二级缓存,但是那个缓存不存储实例只序列化实体。
我在 DoseFrequency 中使用 Tuplizer 得到了这种行为,但我不知道是否有任何其他方法可以实现这一点。
@Entity
@Immutable
@Cacheable
@Cache(region = "dosefrequency", usage = CacheConcurrencyStrategy.READ_ONLY)
@Tuplizer(impl=DoseFrequencyTuplizer.class)
public class DoseFrequency {
....
}
public class DoseFrequencyTuplizer extends PojoEntityTuplizer {
public DoseFrequencyTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
super(entityMetamodel, mappedEntity);
}
@Override
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
return new DoseFrequencyInstantiator(DoseFrequency.class.getName(),entityMetamodel,persistentClass,null);
}
}
public class DoseFrequencyInstantiator implements Instantiator {
private final Class targetClass;
protected PojoEntityInstantiator pojoEntityInstantiator;
public DoseFrequencyInstantiator(String targetClassName, EntityMetamodel entityMetamodel,
PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
try {
this.targetClass = Class.forName(targetClassName);
} catch (ClassNotFoundException e) {
throw new HibernateException(e);
}
pojoEntityInstantiator = new PojoEntityInstantiator(entityMetamodel, persistentClass, optimizer);
}
@Override
public Object instantiate(Serializable id) {
DoseFrequency df = MedereEMRCache.instance.findDoseFrequencyByID(Long.valueOf(id.toString()));
if (df == null) {
return pojoEntityInstantiator.instantiate(id);
}
return df;
}
@Override
public Object instantiate() {
return instantiate(null);
}
@Override
public boolean isInstance(Object object) {
try {
return targetClass.isInstance(object);
} catch (Throwable t) {
throw new HibernateException("could not get handle to entity as interface : " + t);
}
}
}
我知道实例将在应用程序的所有线程之间共享,但它们被视为只读,因此不应修改。
这种方法对吗?
谢谢
【问题讨论】:
标签: java spring hibernate spring-boot orm