Java 为什么GET(JAX-RS)不返回继承的实体特定信息?

Java 为什么GET(JAX-RS)不返回继承的实体特定信息?,java,mysql,jpa,get,jax-rs,Java,Mysql,Jpa,Get,Jax Rs,我正在Glassfish 3.1.2服务器上运行RESTful web服务。我使用Jersey作为JAX-RS实现,Jackson作为JSON提供程序,JPA EclipseLink 2.5作为MySQL的持久性提供程序 我将介绍一些上下文,然后问我的问题。 假设我们有以下层次结构:Item实体和继承它的CraftableItem实体请参见下面的代码示例。它们都有相应的EAO和资源类:ItemEAO、CraftableItemEAO+ItemResource、CraftableItemResou

我正在Glassfish 3.1.2服务器上运行RESTful web服务。我使用Jersey作为JAX-RS实现,Jackson作为JSON提供程序,JPA EclipseLink 2.5作为MySQL的持久性提供程序

我将介绍一些上下文,然后问我的问题。 假设我们有以下层次结构:Item实体和继承它的CraftableItem实体请参见下面的代码示例。它们都有相应的EAO和资源类:ItemEAO、CraftableItemEAO+ItemResource、CraftableItemResource请参见下面的代码示例

让我们在items表中有两条记录:

以及一个对应的可手工制作的记录,用于制作所加入的物品:

我希望从get/item请求中获得关于每个实体的更多具体信息。我希望它返回[{id:1,name:craftable,crafting_time:120000},{id:2,name:non-craftable}]。此时,GET/item/1返回{id:1,name:craftable,crafting_-time:120000},而GET/item/2只返回{id:2,name:non-craftable},这是我想要的行为,但是对于GET/item来说。正在获取有关当前实体的所有信息

出于理智的考虑,代码示例设置器被省略

@MappedSuperclass
public abstract class BaseEntity {

    protected Long id;
    
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "items")
public class Item extends BaseEntity implements Serializable {
    
    private String name;

    @Column(name = "name", nullable = false, unique = true)
    public String getName() {
        return name;
    }
}

@Entity
@DiscriminatorValue("craftable")
@Table(name = "craftable_items_joined")
public class CraftableItem extends Item {
    
    protected long craftingTime;

    @Column(name = "crafting_time", nullable = false)
    public long getCraftingTime() {
        return craftingTime;
    }
}
EAO然后:

public abstract class AbstractEAO<T> {

    private Class<T> entityClass;

    public AbstractEAO(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    public Class<T> getEntityClass() {
        return entityClass;
    }

    protected abstract EntityManager getEntityManager();

    // create, edit, remove

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }
}

@Stateless
@LocalBean
public class ItemEAO extends AbstractEAO<Item> {

    @PersistenceContext(unitName = "primary")
    private EntityManager entityManager;

    public ItemEAO() {
        super(Item.class);
    }
    
    @Override
    protected EntityManager getEntityManager() {
        return entityManager;
    } 
}

@Stateless
@LocalBean
public class CraftableItemEAO extends AbstractEAO<CraftableItem> {
    
    @PersistenceContext(unitName = "primary")
    private EntityManager entityManager;

    public CraftableItemEAO() {
        super(CraftableItem.class);
    }
    
    @Override
    protected EntityManager getEntityManager() {
        return entityManager;
    }    
}
资源最后:

public abstract class AbstractResource<T extends BaseEntity> {
    
    protected abstract AbstractEAO<T> getEAO();
    
    @GET
    public List<T> findAll() {
        return getEAO().findAll();
    }
    
    @GET
    @Path("{id}")
    public T find(@PathParam("id") Long id) {
        return getEAO().find(id);
    }

    // create, edit, remove
}

@Stateless
@Path("item")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ItemResource extends AbstractResource<Item> {

    @EJB private ItemEAO itemEAO;
    
    @Override
    protected AbstractEAO<Item> getEAO() {
        return itemEAO;
    }
}

@Stateless
@Path("item/craftable")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CraftableItemResource extends AbstractResource<CraftableItem> {
    
    @EJB private CraftableItemEAO craftableItemEAO;

    @Override
    protected AbstractEAO<CraftableItem> getEAO() {
        return craftableItemEAO;
    }
}

我不明白你在问什么,问题是什么。我读了你的问题,因为我希望它返回foo,它返回foo,这就是我想要的。那么,有什么问题吗?不完全是。我只在单个资源请求get/item/{id}上获得子类中指定的特定信息,这正是我想要的。但是在多个资源请求上,GET/item并没有发生——我只得到在超类中为每个entity.Hi指定的公共信息。你解决问题了吗?我也有类似的问题。
public abstract class AbstractEAO<T> {

    private Class<T> entityClass;

    public AbstractEAO(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    public Class<T> getEntityClass() {
        return entityClass;
    }

    protected abstract EntityManager getEntityManager();

    // create, edit, remove

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }
}

@Stateless
@LocalBean
public class ItemEAO extends AbstractEAO<Item> {

    @PersistenceContext(unitName = "primary")
    private EntityManager entityManager;

    public ItemEAO() {
        super(Item.class);
    }
    
    @Override
    protected EntityManager getEntityManager() {
        return entityManager;
    } 
}

@Stateless
@LocalBean
public class CraftableItemEAO extends AbstractEAO<CraftableItem> {
    
    @PersistenceContext(unitName = "primary")
    private EntityManager entityManager;

    public CraftableItemEAO() {
        super(CraftableItem.class);
    }
    
    @Override
    protected EntityManager getEntityManager() {
        return entityManager;
    }    
}
public abstract class AbstractResource<T extends BaseEntity> {
    
    protected abstract AbstractEAO<T> getEAO();
    
    @GET
    public List<T> findAll() {
        return getEAO().findAll();
    }
    
    @GET
    @Path("{id}")
    public T find(@PathParam("id") Long id) {
        return getEAO().find(id);
    }

    // create, edit, remove
}

@Stateless
@Path("item")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ItemResource extends AbstractResource<Item> {

    @EJB private ItemEAO itemEAO;
    
    @Override
    protected AbstractEAO<Item> getEAO() {
        return itemEAO;
    }
}

@Stateless
@Path("item/craftable")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class CraftableItemResource extends AbstractResource<CraftableItem> {
    
    @EJB private CraftableItemEAO craftableItemEAO;

    @Override
    protected AbstractEAO<CraftableItem> getEAO() {
        return craftableItemEAO;
    }
}