gpt4 book ai didi

java - 使用 jpa 在 jax-rs Rest 服务中使用泛型的障碍

转载 作者:太空宇宙 更新时间:2023-11-04 06:08:46 24 4
gpt4 key购买 nike

我正在编写一个公开关系数据库的休息服务。我的应用程序有三层:

  1. 持久层(JPA 实体)
  2. EJB层
  3. 休息层

对于每个实体,我正在实现的方法是:addupdatefindAllfindById。我在 Rest 层EJB 层 中使用 Java 泛型,以便编写尽可能少的代码。

但是我在EJB层实现findById方法时遇到了障碍,因为数据库的某些实体具有Integer类型主键,而其他实体具有String类型主键。通用 EJB 实现如下:

public abstract class SimpleEJB <T extends Object> {

//This entity is injected by the container.
@PersistenceContext(name="PersistenceUnit")
private EntityManager em;

private Class<?> TClass;

public SimpleEJB(Class<?> entityClass){
this.TClass = entityClass;
}

public T findById(String id){
T t = this.em.find(this.TClass, id);
return t;
}
}

我不想为我可能找到的每个不同的主键类型(整数、字符串、日期等)编写抽象类(在剩余层和 ejb 层上)。由于其余层在 url 中接收作为 String 的主键,我是否可以将该 String 传递给 EJB 层,并且 find 方法 EntityManager 是否会自动将该 String 转换为 T 类型,或者我是否被迫为每个不同的主键类型编写不同的抽象类?

附注:我无法更改数据库。

最佳答案

我认为您可以对 TClass 进行一些反射来获取 id 字段的类型(假设这是“id”字段的通用名称),然后有条件地设置 PK 来检查 。类似的东西

public T findById(String id) throws Exception {
Field idField = TClass.getDeclaredField("id");
Class<?> type = idField.getType();
Object pk = id;
if (type == Integer.class) {
pk = Integer.parseInt(id);
}
return manager.find(TClass, pk);
}

对于更通用的方法(您不需要知道字段的名称),您也可以检查所有字段上的 @Id 注释。无论哪一个带有注释,都将是您要解析的类型。例如

public T findById(String id) throws Exception {
Field[] declaredFields = TClass.getDeclaredFields();
Field idField = null;
for (Field field: declaredFields) {
if (field.isAnnotationPresent(Id.class)) {
idField = field;
break;
}
}
if (idField == null) {
throw new IllegalStateException("No field annotated with @Id");
}
Class<?> type = idField.getType();
Object pk = id;
if (type == Integer.class) {
pk = Integer.parseInt(id);
}
return manager.find(TClass, pk);
}

关于java - 使用 jpa 在 jax-rs Rest 服务中使用泛型的障碍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29001772/

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