簡體   English   中英

在 spring 數據 jpa 投影中使用嵌入值對象

[英]Using embedded value objects in spring data jpa projections

我正在使用 Spring Boot 2.0RC2,在我閱讀的文檔中,您可以在調用存儲庫時返回實體的投影而不是整個實體。 如果我在實體中使用字符串,但在使用嵌入的值對象時則不然,這可以正常工作。

假設我有Product實體:

@Entity
@Table(name = "t_product")
public class Product extends BaseEntity {

    @Column(nullable = false)
    private String name;

    private Product() {}

    private Product(final String name) {
        this.name = name;
    }

    public static Result<Product> create(@NonNull final String name) {
        return Result.ok(new Product(name));
    }

    public String getName() {
        return name;
    }

    public void setName(@NonNull final String name) {
        this.name = name;
    }
}

BaseEntity僅包含idcreatedupdated屬性。

我有一個名為ProductSummary投影界面:

interface ProductSummary {
    String getName();
    Long getNameLength();
}

在我的ProductRepository我有以下返回ProductSummary方法:

public interface ProductRepository extends JpaRepository<Product, Long> {
    @Query(value = "SELECT p.name as name, LENGTH(p.name) as nameLength FROM Product p WHERE p.id = :id")
    ProductSummary findSummaryById(@Param("id") Long id);
}

這工作得很好。 現在假設我正在執行 DDD,而不是使用 String 來表示Product實體中的name屬性,我想使用一個名為Name的值對象:

@Embeddable
public class Name implements Serializable {

    public static final int MAX_NAME_LENGTH = 100;

    @Column(nullable = false, length = Name.MAX_NAME_LENGTH)
    private String value;

    private Name() {}

    private Name(final String value) {
        this.value = value;
    }

    public static Result<Name> create(@NonNull final String name) {
        if (name.isEmpty()) {
            return Result.fail("Name cannot be empty");
        }

        if (name.length() > MAX_NAME_LENGTH) {
            return Result.fail("Name cannot be longer than " + MAX_NAME_LENGTH + " characters");
        }

        return Result.ok(new Name(name));
    }

    public String getValue() {
        return value;
    }
}

我將我的Product實體更改為:

@Entity
@Table(name = "t_product")
public class Product extends BaseEntity {

    @Embedded
    private Name name;

    private Product() {}

    private Product(final Name name) {
        this.name = name;
    }

    public static Result<Product> create(@NonNull final Name name) {
        return Result.ok(new Product(name));
    }

    public Name getName() {
        return name;
    }

    public void setName(final Name name) {
        this.name = name;
    }
}

ProductSummary我將返回類型從String更改為Name

當我運行時,我總是得到異常:

Caused by: java.lang.IllegalAccessError: tried to access class com.acme.core.product.ProductSummary from class com.sun.proxy.$Proxy112

我可以做這項工作還是我錯過了一些不允許這樣做的限制?

如果您希望獲得完整的 Name 字段(不是 Name 類中的特定字段),那么您需要創建另一個接口,如 ProductSummary。

interface ProductSummary {
    NameSummary getName();

    interface NameSummary {
      String getValue();
    }
}

無需更改存儲庫中的任何內容。

這里有很清楚的記錄

並確保您的接口和方法是公開的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM