Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
如果我使用hibernate持久化一个类,如何确保在创建其他字段的同时合并某些字段的值?_Hibernate_Orm_Jpa_Merge_Persistence - Fatal编程技术网

如果我使用hibernate持久化一个类,如何确保在创建其他字段的同时合并某些字段的值?

如果我使用hibernate持久化一个类,如何确保在创建其他字段的同时合并某些字段的值?,hibernate,orm,jpa,merge,persistence,Hibernate,Orm,Jpa,Merge,Persistence,假设我有一个带有字段type和purchaseDate的类'Cheese',这样: public class Cheese{ CheeseType cheeseType; String purchaseDate; public setPurchaseDate(String value){ purchaseDate=value; } public Class CheeseType{ String type; public

假设我有一个带有字段type和purchaseDate的类'Cheese',这样:

public class Cheese{
    CheeseType cheeseType;
    String purchaseDate;

    public setPurchaseDate(String value){
      purchaseDate=value;
      }

public Class CheeseType{
      String type;

      public setType(String value){
         type=value;
         }

public class MyClass{
     Cheese cheese = new Cheese();
     cheese.setType("cedar");
     cheese.setPurchaseDate("01/02/03");
     // Code to get entity manager etc
     em.getTransaction().begin();
     em.persist(cheese);
     em.getTransaction().commit();
     // Code to close entity manager etc
     }
请忽略代码中的任何愚蠢错误,我已尝试简化我的问题

很明显,在现实世界中会有很多其他参数,但在这种情况下:同一个purchaseDate可以在数据库中存在很多次(就像我买奶酪一样多!),但“type”已经存在于数据库中(比如说,以前的购买)。现在,每当我将一个“Cheese”实例持久化到数据库中时,就会添加一个新的“CheeseType”,即有多个“cedar”。如何让每个“Cheese”实例检查已经存在的CheeseType,而不是在数据库中创建多个新的Cedar?我想我需要在某个地方合并,但我看到的例子似乎与我尝试做的事情不一样


如果有人有任何建议,我将非常感谢听到他们!如果我在这里犯了任何新手错误,请道歉

如果cheese类型存储在它自己的表中,那么应该为它创建一个映射。类似地,您也应该有一个Cheese映射,定义如何映射其属性。您可以在那里指定Cheese和CheeseType之间的关联

为此,CheeseType需要一个唯一标识其实例的标识符。这允许您知道两个CheeseType对象都具有
type=“cheddar”
实际上是同一个逻辑实例。一个明显的可能性是
类型
字段,但通常最好使用生成的内部ID

有关更多详细信息,请参阅Hibernate参考中的

如何让每个“Cheese”实例检查已有的
CheeseType
,而不是在数据库中创建多个新的Cedar

我不知道这是否适合您的需要,但是如果您知道您已经有了
“cedar”
CheeckType
(假设
CheeseType
是一个实体,
“cedar”
是标识符-您的示例不清楚/不连贯),那么您可以使用
会话加载(),或
EntityManager#getReference()
如果使用JPA,则在创建新的
奶酪时设置关联,如下所示:

 em.getTransaction().begin();

 CheeseType type = em.getReference(CheeseType.class, "cedar"); // no db hit 

 Cheese cheese = new Cheese();
 cheese.setType(type);
 cheese.setPurchaseDate("01/02/03");

 em.persist(cheese);
 em.getTransaction().commit();

如果您不知道是否已经有了
“cedar”
CheeseType
,那么您确实可以尝试
合并。以下是JPA规范第3.2.4.1节所述内容:

应用于实体X的
merge
操作的语义如下:如果X是新的实体实例,则创建新的托管实体实例X1,并将X的状态复制到新的托管实体实例X1中

因此,
merge
将根据实体的状态进行插入/更新。但是一定要真正了解
merge
的工作原理(参见下面的链接),在我看来,合并并不是一个显而易见的概念

资源
  • Hibernate实体管理器参考指南
相关问题