JPA和JSON运算符本机查询

时间:2017-03-20 10:29:55

标签: java json postgresql jpa hibernate-native-query

我正在尝试使此查询在JPA中起作用:

SELECT * FROM contrat WHERE contrat_json @> '{"nom" :"hever"}';

它与postgresql完美配合,但当我将其与JPA集成时,我收到以下错误:

  

该位置[1]的参数不存在

我的代码:

 @Transactional
 @Query(nativeQuery = true,value = "select p from Contrat p where contrat_json @> '{\"nom\":\":nom\"}'")
    public List<Contrat> findByNomRestrict(@Param("nom") String nom);

我认为尽管有原生查询,但它无法识别@>,您有什么想法吗?

3 个答案:

答案 0 :(得分:2)

使用PostgreSQL和JSON,您可能会遇到需要@XmlType(name = "tPessoa") @XmlEnum public enum TPessoa { @XmlEnumValue("pf") PF("pf"), @XmlEnumValue("pj") PJ("pj"); private final String value; TPessoa(String v) { value = v; } public String value() { return value; } public static TPessoa fromValue(String v) { if(("F".equalsIgnoreCase(v)) || ("PF".equalsIgnoreCase(v))) return PF; if(("J".equalsIgnoreCase(v)) || ("PJ".equalsIgnoreCase(v))) return PJ; throw new IllegalArgumentException(v); } } 或其他奇怪的操作符,所以最好只使用它们的功能等价物。您可以在?控制台中查找它们,例如psql

您的查询不是原生的,如参数所示。

\doS+ @>

只有在到达数据库时才会出错。

尝试类似

的内容
select p from Contrat p where...

并绑定@Query(nativeQuery = true, value = "select * from Contrat where jsonb_contains(contrat_json, :nom )") 作为参数

答案 1 :(得分:1)

在文字内部不理解参数持有者:'...:nom...'将包含字符:nom,而不是nom的绑定值。

对于PostgreSQL 9.5(及更高版本),请使用:

SELECT * FROM contrat WHERE contrat_json @> jsonb_build_object('nom', :nom)

对于9.4:

SELECT * FROM contrat WHERE contrat_json @> CAST(json_build_object('nom', :nom) AS jsonb)

对于9.3(及更早版本),没有JSON包含运算符(jsonb类型都没有。)

http://rextester.com/AUHP11519

答案 2 :(得分:1)

我的原生查询遇到了类似的问题。 jsonb字段名称称为数据,它很简单

{ 
   "name" : "genderList", 
   "displayName" : "gender list" 
}

我想通过名字找到JpaRepository,这里是我的存储库

@Repository
public interface LookupListRepository extends JpaRepository<LookupList, UUID>
{
    @Query(value = "SELECT * FROM lookup_list WHERE data->>'name' = :name", 
            nativeQuery = true)
    List<LookupList> findByName(@Param("name") String name);
}

您需要 nativeQuery = true 。 使用 nativeQuery = true ,这也可以。

SELECT * FROM lookup_list WHERE jsonb_extract_path_text(data, 'name') = :name

我看到你的@Transactional注释,我假设你在应用服务方法之上有本机查询。您是否可以尝试在存储库中移动所有本机查询并使用JpaRepository,并在应用程序服务中使用存储库方法? 以下是我的应用程序服务使用存储库的方式。

public class LookupListServiceImpl implements LookupListService
{
    @Autowired
    LookupListRepository lookupListRepository;

    @Override
    @Transactional
    public void changeLookupList(LookupListDto lookupListDto)
    {
        List<LookupList> lookupLists = lookupListRepository.findByName(lookupListDto.getName());
        ...
    }

}

JPA存储库的参考 http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html