Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JPA管理复合对象并正确映射其属性_Jpa_Domain Driven Design_Domain Model_Object Composition - Fatal编程技术网

使用JPA管理复合对象并正确映射其属性

使用JPA管理复合对象并正确映射其属性,jpa,domain-driven-design,domain-model,object-composition,Jpa,Domain Driven Design,Domain Model,Object Composition,再一次,我遇到了一些十字路口,这些十字路口让我与“丰富”领域模型对象的对象组合设计的正确原则作斗争 请注意,组合的含义是UML建模带来的含义:当有人声明一个对象包含另一个对象或一组对象时,所包含对象(或一组对象)的生命附加到(或取决于)容器对象的生命 让我们举个例子,这样我就可以直接展示我的观点。假设我们有一家食品店,它存储“食品”请求,每个请求都是由一个或多个订单组成的,订单仅由一个食品和一个数量来描述。所以,让我用UML图来演示这个场景--> 基本上我们有三类:Request、Order和F

再一次,我遇到了一些十字路口,这些十字路口让我与“丰富”领域模型对象的对象组合设计的正确原则作斗争

请注意,组合的含义是UML建模带来的含义:当有人声明一个对象包含另一个对象或一组对象时,所包含对象(或一组对象)的生命附加到(或取决于)容器对象的生命

让我们举个例子,这样我就可以直接展示我的观点。假设我们有一家食品店,它存储“食品”请求,每个请求都是由一个或多个订单组成的,订单仅由一个食品和一个数量来描述。所以,让我用UML图来演示这个场景-->

基本上我们有三类:
Request
Order
Food
。请允许我澄清一下,没有一种可以想象的方式来处理不属于请求的顺序

之后,我开始编写代码。我得出了两个不同的方案,但在展示两个方案之间的差异之前,让我们先写下共同类食物

/**
 * Each object represent diferents types of food.
 */
public enum Food
{
    PIZZA,
    HAMBURGUER,
    ANOTHER_TYPE_OF_FOOD
}
嗯,是的。。你说得对,我说过那是一门课。。。这是一种具有广为人知的对象的类(毕竟,我想枚举是关于对象的)

(第一项计划) 这是
订单

请注意方法
等于
hashCode

这是
请求
类:

请注意方法
placeOrder

/**
 * An instance of Request represents a concrete meal request, belonging to a client, that may include various types of food.
 * NOTE : The request is _composing_ order objects. Order object instantiation and destruction is handled INSIDE this class only.
 */
public class Request
{
    private List<Order> orders; // one-to-many, with COMPOSITION, so the Request OWNS each order (not AGGREGATION) (the ORDER needs to BE WITHIN a Request, if not it can´t exists)

    public Request()
    {
    }

    public void placeOrder (Food food, int quantity) 
    {
        Order order = new Order(food, quantity);
        int index =  orders.indexOf(order);
        if (index != -1)
        {
            Order storedOrder = orders.get(index);
            storedOrder.incQuantity(quantity);
        }
        else 
        {
            orders.add(order);
        }
    }
}
/**
 * An instance of Request represents a concretre request for food in behalf of a client.
 * NOTE : The request is _composing_ order objects. Order objetc instancition and destruction
 * is handled INSIDE this class only.
 */
public class Request
{
    private Client client; // one-to-one
    private Map<Food,Order> orders; // one-to-many, so the Request OWNS each order (not AGGREGATION) (the ORDER needs to BE WITHIN a Request, if not it can´t exists)

    public Request()
    {
    }

    public void placeOrder (Food food, int quantity) 
    {
        if (orders.containsKey(food)) 
        {
            orders.get(food).incQuantity(quantity);
        }
        else 
        {
            orders.put(food, new Order(food, quantity));
        }
    }

}
这是
请求
类:

请再次注意,方法
placeOrder

/**
 * An instance of Request represents a concrete meal request, belonging to a client, that may include various types of food.
 * NOTE : The request is _composing_ order objects. Order object instantiation and destruction is handled INSIDE this class only.
 */
public class Request
{
    private List<Order> orders; // one-to-many, with COMPOSITION, so the Request OWNS each order (not AGGREGATION) (the ORDER needs to BE WITHIN a Request, if not it can´t exists)

    public Request()
    {
    }

    public void placeOrder (Food food, int quantity) 
    {
        Order order = new Order(food, quantity);
        int index =  orders.indexOf(order);
        if (index != -1)
        {
            Order storedOrder = orders.get(index);
            storedOrder.incQuantity(quantity);
        }
        else 
        {
            orders.add(order);
        }
    }
}
/**
 * An instance of Request represents a concretre request for food in behalf of a client.
 * NOTE : The request is _composing_ order objects. Order objetc instancition and destruction
 * is handled INSIDE this class only.
 */
public class Request
{
    private Client client; // one-to-one
    private Map<Food,Order> orders; // one-to-many, so the Request OWNS each order (not AGGREGATION) (the ORDER needs to BE WITHIN a Request, if not it can´t exists)

    public Request()
    {
    }

    public void placeOrder (Food food, int quantity) 
    {
        if (orders.containsKey(food)) 
        {
            orders.get(food).incQuantity(quantity);
        }
        else 
        {
            orders.put(food, new Order(food, quantity));
        }
    }

}
上述方法使用的是聚合,通过这种方式,我将创建和销毁工作委托给了另一个超出范围的上层模块,可能是服务层中的一个模块,这使得我的所有域模型类都非常匮乏,指的是封装行为差、只包含状态的类。这是我不想要的,因为我想要一个丰富的模型,在这个意义上,in包含一些业务逻辑,部分业务逻辑是关于实例化的(这是一个真实的历史,让我们面对it人员)

最后,问题是: 1) 最好的方法是什么?显然,我愿意看到新的视角

2) (更懒散的问题)为了使用ORM,我应该给类添加JPA注释吗

好吧,谢谢大家

格雷廷斯

维克托


我的一个非常相关的问题是

如果您认为第二种方案更接近域,我建议您使用混合解决方案。关键是使用列表表示持久性,而使用映射表示域

public class Request {
    private List<Order> orders = new ArrayList<Order>(); //this is easy to persist

    public void placeOrder (Food food, int quantity) {
        //uses orders() everytime you want to manipulate the orders
        final Map<Food, Order> orders = orders(); 
        if (orders.containsKey(food)) {
            orders.get(food).incQuantity(quantity);
        } else {
            orders.put(food, new Order(food, quantity));
        }
    }

    private Map<Food, Order> orders() {
        final Map<Food, Order> map = new HashMap<Food, Order>();
        for (Order order: this.orders) {
            map.put(order.getFood(), order);
        }
        return map;
    }
}
公共类请求{
private List orders=new ArrayList();//这很容易持久化
公共订单(食品,整数数量){
//每次要操作订单时都使用orders()
最终地图订单=订单();
if(订单.集装箱(食品)){
订单。获取(食物)。增加数量(数量);
}否则{
下单。下单(食品、新订单(食品、数量));
}
}
私人地图订单(){
final Map=new HashMap();
for(订单:this.orders){
map.put(order.getFood(),order);
}
返回图;
}
}
此解决方案使域模型受持久性实现的影响最小。主要的缺点是,这将为将订单列表转换为订单映射带来一些开销

public class Request {
    private List<Order> orders = new ArrayList<Order>(); //this is easy to persist

    public void placeOrder (Food food, int quantity) {
        //uses orders() everytime you want to manipulate the orders
        final Map<Food, Order> orders = orders(); 
        if (orders.containsKey(food)) {
            orders.get(food).incQuantity(quantity);
        } else {
            orders.put(food, new Order(food, quantity));
        }
    }

    private Map<Food, Order> orders() {
        final Map<Food, Order> map = new HashMap<Food, Order>();
        for (Order order: this.orders) {
            map.put(order.getFood(), order);
        }
        return map;
    }
}