【发布时间】:2019-03-10 02:07:36
【问题描述】:
我从支持 sessionscoped cdi bean 访问 ejb 容器中的 EJB dao。 dao 使用连接提取执行 JQL 查询并使用 @OneToMany 引用检索实体。 @OneToMany 集合已填充,我可以在 EJB 中使用它们,但在 CDI 支持 bean 中,集合是空的并被清除。我的实体如下所示:
@Entity
@NamedQuery(name = "order.with.items",
query = "select o from Order o inner join fetch o.item i where o.id=:orderNo")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Version
@Column(name = "version")
private int version;
@Column
private String name;
@OneToMany(mappedBy = "order")
private Set<Item> item = new HashSet<>();;
... getters setters
}
以及被引用项目的:
@Entity
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Version
@Column(name = "version")
private int version;
@Column
private String name;
@ManyToOne
@JoinColumn(name = "order_id", referencedColumnName = "id")
private Order order;
//... getters setters
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass()) // UPDATE: don't do it
return false; // with getClass - use instanceof
Item other = (Item) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (order == null) {
if (other.order != null)
return false;
} else if (!order.equals(other.order))
return false;
return true;
}
}
和道:
@Stateless
@LocalBean
public class OrderDao {
@PersistenceContext(unitName = "jpa-persistence-unit")
protected EntityManager entityManager;
public Order getOrderWhithItems(Long orderId) {
Order order = entityManager.createNamedQuery("order.with.items",Order.class).setParameter("orderId", orderId).getSingleResult();
// Here is the size greater than zero
System.out.println("# of items: " + order.getItem().size());
return order;
}
}
和支持 bean:
@Named
@SessionScoped
public class BackingBean {
@EJB
private OrderDao orderDao;
public BackingBean() {
Order order = orderDao.getOrderWhithItems( 4L);
Set<Item> items = order.getItem();
// This will ouputs 0
System.out.println("# of items " + items.size());
}
}
问题是,order 包含 dao 方法中的所有项目,但是当 backing bean 接收到订单时,项目被撕掉并且集合为空。我还编写了一个 arquillian junit 测试来测试其中的 dao,它运行良好,并且订单包含测试中的项目。但不在 CDI 会话 bean 中。当我像 DTO(数据传输对象)一样提取 dao 中的集合时,我可以接收支持 bean 中的项目。
dao bean 位于 ejb jar 中,位于 ear 企业档案中。 CDI 支持 bean 位于同一耳朵的战争档案中。我将我们的问题案例简化为订单项目示例。我找不到这种愚蠢行为的任何资源。我使用 wildfly 13 appserver 并使用 hibernate jpa orm。
【问题讨论】:
标签: java hibernate jpa ejb wildfly