【问题标题】:Difference between @MapKey, @MapKeyColumn and @MapKeyJoinColumn in JPA and HibernateJPA和Hibernate中@MapKey、@MapKeyColumn和@MapKeyJoinColumn的区别
【发布时间】:2014-10-15 21:10:54
【问题描述】:

根据Hibernate documentation,如果我们想使用 Map 作为实体之间的关联,可以使用多个注释。医生说:

或者,映射键被映射到一个或多个专用列。 为了自定义映射使用以下之一 注释:

@MapKeyColumn 如果映射键是基本类型。如果您不指定 列名,属性名后跟下划线 通过 KEY 使用(例如 orders_KEY)。 @MapKeyEnumerated / @MapKeyTemporal 如果映射键类型分别是枚举或日期。 @MapKeyJoinColumn/@MapKeyJoinColumns 如果映射键类型是另一个 实体。 @AttributeOverride/@AttributeOverrides 当映射键是 可嵌入对象。使用钥匙。作为可嵌入对象的前缀 属性名称。也可以使用@MapKeyClass 来定义类型 如果您不使用泛型,则为关键。

通过一些示例,我可以理解@MapKey 仅用于将键映射到目标实体的属性,并且该键仅用于获取记录。 @MapKeyColumn 用于将键映射到目标实体的属性,该键用于保存和获取记录。请告诉我这是否正确?

当我需要使用@MapKeyJoinColumn/@MapKeyJoinColumns & @MapKeyEnumerated / @MapKeyTemporal 时请告诉我

谢谢!

【问题讨论】:

    标签: java hibernate jpa orm hibernate-mapping


    【解决方案1】:

    这是一个将@MapKey 与@OneToMany 与复合@IdClass 一起使用的工作示例。这显然不是实现这里目标的唯一方法,但我觉得这是最可维护的。

    @Entity
    @Table(name = "template_categories")
    @IdClass(TemplateCategoryId.class)
    public class TemplateCategory implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        long orgId;
        @Id
        long templateId;
    
        @OneToMany(targetEntity = TemplateEntry.class)
        @JoinColumns( {
            @JoinColumn(name = "orgId",  referencedColumnName = "orgId"),
            @JoinColumn(name = "templateId",  referencedColumnName = "templateId")
            }
        )
        @MapKey(name="key")
        private Map<String, TemplateEntry> keyMap;
    

    源代码: https://github.com/in-the-keyhole/jpa-entity-map-examples/blob/master/src/main/java/com/example/demo/mapkey/entity/TemplateCategory.java

    【讨论】:

      【解决方案2】:

      当您使用Map 时,您始终需要关联至少两个实体。假设我们有一个与Car 实体相关的Owner 实体(CarOwner 有一个FK)。

      所以,Owner 将有一个 MapCar(s)

      Map<X, Car>
      

      @MapKey

      @MapKey 将为您提供Car's 属性,用于将Car 分组到其Owner。例如,如果我们在Car 中有一个vin(车辆识别号)属性,我们可以将其用作carMap 键:

      @Entity
      public class Owner {
          @Id
          private long id;
      
          @OneToMany(mappedBy="owner")
          @MapKey(name = "vin")
          private Map<String, Car> carMap;
      }
      
      @Entity
      public class Car {
          @Id
          private long id;
      
          @ManyToOne
          private Owner owner;
      
          private String vin;
      
      }
      

      @MapKeyEnumerated

      @MapKeyEnumerated 将使用来自Car 的枚举,例如WheelDrive

      @Entity
      public class Owner {
          @Id
          private long id;
      
          @OneToMany(mappedBy="owner")
          @MapKeyEnumerated(EnumType.STRING)
          private Map<WheelDrive, Car> carMap;
      }
      
      @Entity
      public class Car {
          @Id
          private long id;
      
          @ManyToOne
          private Owner owner;
      
          @Column(name = "wheelDrive")
          @Enumerated(EnumType.STRING)
          private WheelDrive wheelDrive;
      
      }
      
      public enum WheelDrive {
          2WD, 
          4WD;             
      }
      

      这将按照车轮驱动类型对汽车进行分组。

      @MapKeyTemporal

      @MapKeyTemporal 将使用Date/Calendar 字段进行分组,例如createdOn

      @Entity
      public class Owner {
          @Id
          private long id;
      
          @OneToMany(mappedBy="owner")
          @MapKeyTemporal(TemporalType.TIMESTAMP)
          private Map<Date, Car> carMap;
      }
      
      @Entity
      public class Car {
          @Id
          private long id;
      
          @ManyToOne
          private Owner owner;
      
          @Temporal(TemporalType.TIMESTAMP)
          @Column(name="created_on")
          private Calendar createdOn;         
      }
      

      @MapKeyJoinColumn

      @MapKeyJoinColumn 需要第三个实体,例如 Manufacturer,以便您拥有从 OwnerCar 的关联,并且 car 还具有与 Manufacturer 的关联,这样您就可以对所有 @987654358 进行分组@CarsManufacturer:

      @Entity
      public class Owner {
          @Id
          private long id;
      
          @OneToMany(mappedBy="owner")
          @MapKeyJoinColumn(name="manufacturer_id")
          private Map<Manufacturer, Car> carMap;
      }
      
      @Entity
      public class Car {
          @Id
          private long id;
      
          @ManyToOne
          private Owner owner;
      
          @ManyToOne
          @JoinColumn(name = "manufacturer_id")
          private Manufacturer manufacturer;          
      }
      
      @Entity
      public class Manufacturer {
          @Id
          private long id;
      
          private String name;
      }
      

      【讨论】:

      • 嗨,弗拉德,如果可能的话,请您看看我的另一篇帖子 - stackoverflow.com/questions/25664452/… 非常感谢您的支持。
      • 今晚我去看看
      • 我也有类似的问题。出于某种原因,@MapKey 没有给我预期的结果。你也可以看看这个:stackoverflow.com/questions/31235462/… 吗? ^^
      • @VladMihalcea 目前我正在从hibernate 3.3.2 迁移到hibernate 4.3.11。如何迁移@MapKey导致MapKey无法解析为hiberante4中的类型
      • 我在度假。我回来看看。
      猜你喜欢
      • 2013-02-06
      • 2011-11-17
      • 2013-01-13
      • 2011-04-23
      • 2011-08-06
      • 2011-05-29
      • 2010-10-31
      • 2012-04-10
      相关资源
      最近更新 更多