如何在SpringBoot中使用Hibernate @NaturalId?

栏目: Java · 发布时间: 7年前

内容简介:这是一个Spring Boot应用程序案例,展示如何使用Hibernate映射自然业务键  @NaturalId。关键点:1.在实体(例如,Product)中,标记应作为自然ID 的属性(业务键)  @NaturalId; 通常,实体中只有一个这样的属性,但是

这是一个Spring Boot应用程序案例,展示如何使用Hibernate映射自然业务键  @NaturalId。

关键点:

1.在实体(例如,Product)中,标记应作为自然ID 的属性(业务键)  @NaturalId; 通常,实体中只有一个这样的属性,但是 这里 也支持多个属性。

@Entity
<b>public</b> <b>class</b> Product implements Serializable {

    <b>private</b> <b>static</b> <b>final</b> <b>long</b> serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    <b>private</b> Long id;

    <b>private</b> String name;

    @NaturalId(mutable = false)
    @Column(nullable = false, updatable = false, unique = <b>true</b>, length = 50)
    <b>private</b> String code;

     <font><i>// @NaturalId(mutable = false)</i></font><font>
    </font><font><i>// @Column(nullable = false, updatable = false, unique = true)</i></font><font>
    </font><font><i>// private Long sku;</i></font><font>
</font>

对于不可变的id,将列标记为@NaturalId(mutable = false)和@Column(nullable = false, updatable = false, unique = true, ...)

对于可变id,将列标记为@NaturalId(mutable = true)和 @Column(nullable = false, updatable = true, unique = true, ...)

2. 使用自然id覆盖equals()和hashCode()

  @Override
    <b>public</b> <b>boolean</b> equals(Object o) {
        <b>if</b> (<b>this</b> == o) {
            <b>return</b> <b>true</b>;
        }
        <b>if</b> (!(o instanceof Product)) {
            <b>return</b> false;
        }
        Product naturalIdProduct = (Product) o;
        <b>return</b> Objects.equals(getCode(), naturalIdProduct.getCode());
        <font><i>// including sku </i></font><font>
        </font><font><i>// return Objects.equals(getCode(), naturalIdProduct.getCode())</i></font><font>
            </font><font><i>// && Objects.equals(getSku(), naturalIdProduct.getSku());</i></font><font>
    }

    @Override
    <b>public</b> <b>int</b> hashCode() {
        <b>return</b> Objects.hash(getCode());
        </font><font><i>// including sku</i></font><font>
        </font><font><i>// return Objects.hash(getCode(), getSku());</i></font><font>
    }

    @Override
    <b>public</b> String toString() {
        <b>return</b> </font><font>"Product{"</font><font> + </font><font>"id="</font><font> + id + </font><font>", name="</font><font> + name + </font><font>", code="</font><font> + code + '}';
        </font><font><i>// including sku</i></font><font>
        </font><font><i>// return "Product{" + "id=" + id + ", name=" + name + ", code=" + code + ", sku=" + sku + '}';</i></font><font>
    }
</font>

3. 定义一个@NoRepositoryBean接口(例如NaturalRepository)来定义两个名为findBySimpleNaturalId()and的方法findByNaturalId()

@NoRepositoryBean
<b>public</b> <b>interface</b> NaturalRepository<T, NID <b>extends</b> Serializable> {

    <font><i>// use this method when your entity has a single field annotated with @NaturalId</i></font><font>
    Optional<T> findBySimpleNaturalId(NID naturalId);
     
    </font><font><i>// use this method when your entity has more than one field annotated with @NaturalId</i></font><font>
    Optional<T> findByNaturalId(Map<String, Object> naturalIds);        
}
</font>

4. 提供此接口的实现(例如,一个NaturalRepositoryImpl实现  )依赖于Hibernate的Session实现 bySimpleNaturalId(),和  byNaturalId()方法

@Repository
@Transactional(readOnly = <b>true</b>)
<b>public</b> <b>abstract</b> <b>class</b> NaturalRepositoryImpl<T, NID <b>extends</b> Serializable>
        implements NaturalRepository<T, NID> {

    @PersistenceContext
    <b>private</b> EntityManager entityManager;

    <b>private</b> <b>final</b> Class<T> entityClass;

    <b>public</b> NaturalRepositoryImpl(Class<T> entityClass) {
        <b>this</b>.entityClass = entityClass;
    }

    @Override
    <b>public</b> Optional<T> findBySimpleNaturalId(NID naturalId) {

        Optional<T> entity = entityManager.unwrap(Session.<b>class</b>)
                .bySimpleNaturalId(entityClass)
                .loadOptional(naturalId);

        <b>return</b> entity;
    }

    @Override
    <b>public</b> Optional<T> findByNaturalId(Map<String, Object> naturalIds) {

        NaturalIdLoadAccess<T> loadAccess
                = entityManager.unwrap(Session.<b>class</b>).byNaturalId(entityClass);
        naturalIds.forEach(loadAccess::using);

        <b>return</b> loadAccess.loadOptional();
    }

}

对于实体,编写扩展的存储库类(例如,用于Product实体写入  ProductNaturalRepository)NaturalRepositoryImpl并使用它来设置实体类类型和自然id类型(当实体使用多个自然ID时,类型不再相关,只需将其设置为Serializable)

45 在您的服务中注入此类并调用findBySimpleNaturalId()或 findByNaturalId()

源代码可 在此处获得


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance Python

High Performance Python

Andrew Lewis / O'Reilly Media, Inc. / 2010-09-15 / USD 34.99

Chapter 1. Introduction Section 1.1. The High Performance Buzz-word Chapter 2. The Theory of Computation Section 2.1. Introduction Section 2.2. Problems Section 2.3. Models of Computati......一起来看看 《High Performance Python》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换