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

时间:2013-10-05 16:15:42

标签: 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和资源类:ItemEAOCraftableItemEAO + ItemResourceCraftableItemResource(请参阅下面的代码示例)。

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

id | name 
 1 | "craftable"
 2 | "non craftable"

crafting_items_joined中“craftable”的一条相应记录:

id | crafting_time
 1 | 120000

我希望尽可能从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。获取有关实体的所有信息。

代码示例(出于理智而省略了setter)。

@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;
    }
}

0 个答案:

没有答案