【问题标题】:JPQL - Spring Boot Repository Query - Map PropertyJPQL - Spring Boot 存储库查询 - 映射属性
【发布时间】:2019-03-01 22:05:08
【问题描述】:

我的域类中有一个映射属性,我正在尝试在存储库中创建一个查询或使用默认的“findByBlah”语法从数据库中提取属性。目前不会工作。我可以轻松地用 SQL 编写查询,但我不知道 JPQL 期望什么。如何使用 JPQL 或接口“findBy”语法从数据库中提取这些数据?无论我当前使用哪种存储库方法,当它从数据库中提取“收集器”时,属性(复杂对象的映射或列表)始终为空。

域对象:

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "collector")
public class Collector {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "collector_id")
    private Long id;

    @NotNull
    private String name;

    @ElementCollection
    @MapKeyColumn(name = "attribute_name")
    @Column(name = "attribute_value")
    @CollectionTable(name = "collector_attributes", joinColumns = @JoinColumn(name = "collector_id"))
    private Map<String, String> attributes;

    @Override
    public String toString() {
        return ObjectUtil.print(this);
    }
}

存储库:

public interface CollectorRepository extends PagingAndSortingRepository<Collector, Long> {

    @Query(value = "select c from Collector c where c.attributes[$1] = $2")
    Page<Collector> findByAttributesNameAndValue(String name, String value, Pageable pageable);
}

这是在 H2 控制台中工作的查询:

SELECT * FROM Collector a INNER JOIN collector_attributes b ON a.collector_id = b.collector_id where b.attribute_name= 'nickName' and b.attribute_value  = 'Critikon'

【问题讨论】:

    标签: sql spring-boot spring-data-jpa jpql


    【解决方案1】:

    唯一对我有用的是定义对象关系而不是地图:

        @ElementCollection
        @CollectionTable(name = "COLLECTOR_ATTRIBUTES", joinColumns = @JoinColumn(name = "COLLECTOR_ID"))
        private List<CollectorAttribute> attributes;
    

    还有嵌入对象

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Setter
    @Embeddable
    public class CollectorAttribute {
    
        @Column(name = "ATTRIBUTE_NAME")
        private String key;
    
        @Column(name = "ATTRIBUTE_VALUE")
        private String value;
    }
    

    现在您可以使用嵌入对象的属性进行查询

    public interface CollectorRepository extends JpaRepository<Collector, Long> {
        List<Collector> findByAttributesKeyAndAttributesValue(String key, String value);
    }
    

    要在 select 中检索 COLLECTOR_ATTRIBUTES,我们可以在 Collector 类和存储库方法中定义一个 @NamedEntityGraph,如下所示

    @NamedEntityGraph(name = "Collector.attributes",
        attributeNodes = @NamedAttributeNode("attributes"))
    @Entity
    @Table(name = "COLLECTOR")
    public class Collector {
    

    并在 Repository 方法中报告 @EntityGraph

    public interface CollectorRepository extends JpaRepository<Collector, Long> {
    
        @EntityGraph(value = "Collector.attributes", type = EntityGraph.EntityGraphType.LOAD)
        List<Collector> findByAttributesKeyAndAttributesValue(String key, String value);
        }
    }
    

    现在你也有了属性

    如果你想在其他方法上也加载属性,你必须使用@EntityGraph

    @EntityGraph(value = "Collector.attributes", type = EntityGraph.EntityGraphType.LOAD)
    Optional<Collector> findById(Long var1);
    

    【讨论】:

    • 这个答案为我编译并将对象持久保存到存储库,但是像上面一样,当存储库查询时收集器属性不会返回。我想我应该把它放在我原来的回复中。我会把它添加到描述中
    • 已加载 CollectorAttribute 的更新答案
    • 由于某种原因,我的列表仍然为空。这对你有用吗?
    • github.com/OpenPCM/openpcm-server/tree/integration-test 这是有这个测试的分支。有一个集成测试因空属性 github.com/OpenPCM/openpcm-server/blob/integration-test/src/… 方法失败:test_read_byId_happy
    • 您在本地尝试吗?在这个 repo 中,我看到 public @ResponseBody Collector readCollector 正在使用 repository.findById(id)。是的 CollectorAttribute 存在。相关属性必须加载 @EntityGraph 定义
    猜你喜欢
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 2018-06-24
    • 1970-01-01
    相关资源
    最近更新 更多