JPQL - запрос репозитория Spring Boot - свойство карты - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть свойство map в классе моего домена, и я пытаюсь создать запрос в репозитории или использовать синтаксис по умолчанию «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'

enter image description here

1 Ответ

0 голосов
/ 26 сентября 2018

Единственное, что мне помогает, это определить отношение Объект вместо карты:

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

И объект enbedded

@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);
}

Для извлечения COLLECTOR_ATTRIBUTES в select мы можем определить @NamedEntityGraph in Collector class и метод репозитория следующим образом

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

и report @EntityGraph inМетод репозитория

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);
...