我一直在使用JPA将我们的系统从手工hibernate转换为spring。到目前为止一切都很顺利。在某种程度上,我发现需要查询实现另一个类的类的所有实例。让我们看看下面的设计:
基类:机器
@Entity
@Table(name = "MACHINE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "Machine")
public abstract class Machine implements Resource {
// ...
}接口:可监控的
public interface Monitorable {
// ...
}子类: Linux
@Entity
@DiscriminatorValue("Linux")
public class Linux extends Machine implements Monitorable {
// ...
}使用Hibernate看起来如下所示:
public static List<Machine> GetALL(Class<?> T) {
// .. hibernate session stuff ..
result = session.createCriteria(T).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY).list();
// .. closing session and error handling.
}我已经有了一个工作机器存储库,我可以很容易地使用findAll()并进行筛选,但这似乎是一种浪费。
在搜索答案时,我发现了一个存储库的以下实现,它允许我们检索所有的子类。
@NoRepositoryBean
public interface BaseMachineRepo<EntityType extends Machine> extends CrudRepository<EntityType, Long> {
@Query("select e from #{#entityName} e")
List<EntityType> findAllByType();
}但是,我不太明白如何将这个实现更改为一个接口而不是一个类。
我得到的最接近的是更改签名:
public interface BaseMachineRepo<EntityType extends Machine & Monitorable> extends CrudRepository<EntityType, Long>然而,这并不能解决这个问题,因为类型不是'Monitorbale‘,而是'Linux’。它不会更改查询,只是对调用方强制执行更多的限制。
谢谢。
编辑:
我知道接口不会影响表本身,否则我就会知道如何查询它。另一方面,编写一个定制的回购程序来检查类型(例如Linux)是否是instanceof --界面感觉是真的不对。
发布于 2018-04-04 12:27:43
这是我最后写到的解决方案:
public class MachineRepoImpl implements MachineRepoCustom {
@Autowired
private MachineRepo machineRepo;
@Autowired
private ApplicationContext applicationContext;
@Override
public List<Machine> findMonitorables() {
List<Machine> machines = machineRepo.findAll();
Map<String, Monitorable> beansOfType = applicationContext.getBeansOfType(Monitorable.class);
Collection<Monitorable> monitorables = beansOfType.values();
Set<Class<? extends Monitorable>> set = new HashSet<>();
List<Machine> result = new ArrayList<Machine>();
// parses monitorable classes
for(Monitorable m : monitorables)
{
set.add(m.getClass());
}
// checks whether the entry in the table is monitorable
for (Machine machine : machines) {
if (set.contains(machine.getClass())) {
result.add(machine);
}
}
return result;
}https://stackoverflow.com/questions/49644618
复制相似问题