gpt4 book ai didi

java - 如何使用 JPA 和 Hibernate 获取关联只读实体的单个实例?

转载 作者:行者123 更新时间:2023-11-30 05:45:48 25 4
gpt4 key购买 nike

我有这两个实体:

@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 的一级缓存中,但加载是在多个 session 中完成的(它是一个 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);
}
}

}

我知道实例将在应用程序的所有线程之间共享,但它们被视为只读,因此不应修改它们。

这种方法正确吗?

谢谢

最佳答案

您还可以使用LoadEventListener来始终服务同一个实例。然而,由于实体是不可变的,因此不需要此功能,因此,即使您有它的多个副本,它仍然是不可变的。

此外,即使您实现了单例模式,它也只会针对每个 JVM 强制执行,因此我不明白您为什么要实现此请求。

实体仅被视为每个 EntityManager 的单例。

关于java - 如何使用 JPA 和 Hibernate 获取关联只读实体的单个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54857459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com