如何在EJB3中的实体中存储复杂对象?

时间:2011-12-17 10:09:12

标签: java-ee properties entity ejb-3.0

我正在开发一个基于EJB3的DVD商店项目。

通过这个项目,客户可以选择DVD并将DVD放入购物车,然后购物车将创建预订记录。

我的问题是我希望保留是一个实体(数据库中的一个表),但它有一个属性ShoppingCart,它是一个复杂的对象;实体不支持存储复杂对象,我不知道如何处理这个问题?

任何人都可以给我任何建议或更好的解决方案吗?

这是班级:

    public class ShoppingCartItem {
      private DVD item;
      private int quantity;
    …
    }

    public class ShoppingCart {
      private HashMap<String, ShoppingCartItem> items;
      private int numberOfItems;
      …
    }

    @Entity
    public class DVD implements Serializable { 
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
      private String title; 
      …
    }


    @Entity
    public class Reservation implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
      //the problem is here
      private ShoppingCart cart;
      …
    }

1 个答案:

答案 0 :(得分:1)

您应该定义有关持久存储感兴趣的ShoppingCart的信息。

在JPA实体(您称之为“EJB 3中的实体”)中,您可以存储:

  • 简单字段(字符串,整数等),
  • embeddables(存储在DB中但没有持久身份的对象 - 换句话说 - 没有“id”),
  • 与其他实体的关系,
  • 任何可序列化的对象。

您的案例似乎是使用第三个或第四个选项解决的。

存储可序列化对象

如果您只想保留整个对象,则应将implements Serializable添加到ShoppingCar,并将其正确保存在数据库中。
但是,它将使用Java Serialization持久化(因此它将是持久性期间传递的对象的二进制表示)。这是实现目标的非常<非常罕见方式。

使用实体关系

您是否考虑过将ShoppingCart作为实体?通过这种方式,您可以在保存Reservation对象时使用关系并保留整个对象,即:

 @Entity
 public class Reservation implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;

      @OneToOne
      private ShoppingCart cart;
      // ...
    }

上面的示例假设只有一个Reservation只与一个ShoppingCart连接。

实现目标的另一种方法是扩展Reservation实体并为订购的产品添加字段,即:

 @Entity
 public class Reservation implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;

      @ElementCollection
      private Map<DVD, Integer> items;
    }

注意使用Map作为接口而不是HashMap,这总是首选(如果JPA不要求。)另请注意,在一个结构中,您可以同时保存 - 项目及其用户购买的数量。

请记住,在此示例中,DVD应该是一个实体(这是非常合理的,因为您可能会将所有项目存储在数据库中。)