Glassfish 3.1.2 サーバーで RESTful Web サービスを実行しています。私は、Jersey を JAX-RS 実装として、Jackson を JSON プロバイダーとして、(JPA) EclipseLink 2.5 を MySQL の永続化プロバイダーとして使用しています。
いくつかのコンテキストを紹介してから、質問をします。次の階層があると仮定しましょう:Item
エンティティとCraftableItem
それを継承するエンティティ (以下のコード サンプルを参照)。両方とも、対応する EAO およびリソース クラスを持っています: ItemEAO
、CraftableItemEAO
+ ItemResource
、CraftableItemResource
(以下のコード サンプルを参照)。
items
テーブルに 2 つのレコードを作成します。
id | name
1 | "craftable"
2 | "non craftable"
および の「作成可能」に対応する 1 つのレコードcrafting_items_joined
:
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
. 存在するエンティティに関するすべての情報を取得しています。
コード サンプル (安全のためにセッターは省略されています)。
@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;
}
}