开发者社区 问答 正文

使用父级从子级存储库中选择

我有一个实体:

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
@DiscriminatorValue("APPEALS")
public class Appeals extends EntityAbstract {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Type(type = "jsonb")
    @Column(name = "content", columnDefinition = "jsonb")
    private String content;

    @Column(name = "guid")
    private String guid;
}

@Getter
@Setter
@Entity
@Table(name = "entity_parent")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING)
//@MappedSuperclass
@TypeDefs({@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)})
public abstract class EntityAbstract implements Content {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    private Integer version;
}

public interface Content {
    String getContent();
    void setContent(String content);
}

我使用Spring Data来处理这个问题。我需要从子表(即APPEALS)中进行选择。我这样做是这样,但它不能那样工作:

public interface EntityRepository extends JpaRepository<EntityAbstract, Long> {
    @Query("SELECT e FROM EntityAbstract e WHERE TYPE(e) = ?1 AND e.guid = ?2")
    <E extends EntityAbstract> E findByContent(final Class<E> e, String content);
}

之后,我将需要使用标准PostgreSql功能在Content字段上进行选择,以搜索jsonb之类的字段。如何在不将content和guid字段传输到AbstractEntity的情况下实现所有这些?

展开
收起
几许相思几点泪 2019-12-15 21:35:02 954 分享 版权
阿里云 AI 助理回答

在您的场景中,您希望使用Spring Data JPA查询子类(即Appeals)并利用PostgreSQL的jsonb类型进行内容搜索。同时,您还希望避免将contentguid字段直接放在抽象父类EntityAbstract中。以下是一些建议来实现您的需求:

1. 修改Repository接口

首先,确保您的Repository接口针对具体实体类进行操作,而不是尝试对抽象类进行泛型查询。修改Repository定义为针对Appeals实体:

public interface AppealsRepository extends JpaRepository<Appeals, Long> {
    // 使用JPA方法命名规则直接查询
    List<Appeals> findByGuidAndContent(String guid, String content);
    
    // 如果需要更复杂的查询,可以使用@Query注解
    @Query("SELECT a FROM Appeals a WHERE a.content @> :content")
    List<Appeals> findByContentJsonb(@Param("content") Map<String, Object> contentMap);
}

2. 利用JSONB查询

对于jsonb类型的字段查询,您可以使用JPA的@Query注解结合PostgreSQL的JSONB操作符。例如,上面的findByContentJsonb方法展示了如何使用@>操作符来查找包含特定JSON内容的记录。

注意,这里假设content字段存储的是可以被解析成Map的JSON数据。如果实际内容是其他格式,请相应调整参数类型和比较逻辑。

3. 移除不必要的字段传输

您提到不想在EntityAbstract中直接包含contentguid字段,实际上,您已经在Appeals实体中定义了这两个字段,所以它们已经属于子类而不影响父类。保持现状即可,无需额外操作来“避免”这些字段的“传输”。

4. JSONB类型映射

确保您的项目配置中包含了正确的类型映射,以便正确处理jsonb字段。您已通过@TypeDefs@Type注解实现了这一点,使用了JsonBinaryType.class。这应该足以让Hibernate识别并正确处理数据库中的jsonb列。

总结

  • 调整Repository接口以直接与具体的子类(Appeals)交互。
  • 利用JPA的方法命名规则或自定义@Query来执行复杂查询,特别是针对jsonb字段的查询。
  • 确保类型映射正确设置,以便于处理JSONB数据类型。

这样,您就可以在不改变抽象基类结构的情况下,有效地从子表中根据条件进行查询,并利用PostgreSQL的jsonb功能。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答