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

时间:2010-09-15 11:37:40

标签: hibernate orm jpa merge persistence

假设我有一个带有字段类型和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',即有多个'Cedars'。如何获取'Cheese'的每个实例来检查CheeseTypes已经存在并且不在数据库中创建多个新的雪松?我想我需要合并到某个地方,但我看到的例子似乎与我想做的事情不一样。

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

2 个答案:

答案 0 :(得分:0)

如果奶酪类型存储在自己的表中,您应该有一个映射。同样,您也应该有一个Cheese的映射,您可以在其中定义如何映射其属性。在那里,您可以指定Cheese和CheeseType之间的关联。

为此,CheeseType需要一个唯一标识其实例的标识符。这允许您知道两个具有type = "cheddar"的CheeseType对象确实是相同的逻辑实例。显而易见的是type字段,但为此目的使用生成的内部ID通常更好。

有关详细信息,请参阅Hibernate Reference中的chapter Mapping associations

答案 1 :(得分:0)

  

我如何获取'Cheese'的每个实例来检查已经存在CheeseType的内容而不是在数据库中创建多个新的雪松?

我不知道这是否符合您的需求,但如果您知道您已经拥有"cedar" CheeckType(假设CheeseType是实体并且"cedar"是标识符 - 您的示例不清晰/连贯),如果您使用JPA,则可以使用Session#load()EntityManager#getReference()来设置创建新关联时的关联Cheese,就像这样:

 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,那么您可以尝试merge。以下是JPA规范,第3.2.4.1节中有关它的内容:

  

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

因此merge将根据实体的状态插入/更新。但请确保真正理解merge的工作方式(参见下面的链接),合并不是IMO的明显概念。

资源

相关问题