简体   繁体   English

JPA和JSON运算符本机查询

[英]JPA and JSON operator native query

I'm trying to make this query work in JPA: 我正在尝试使此查询在JPA中工作:

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

It works perfectly with postgresql but when I integrate it with JPA, I get the following error: 它与postgresql完美配合,但是当我将它与JPA集成时,我收到以下错误:

Parameter with that position [1] did not exist 具有该位置[1]的参数不存在

My code: 我的代码:

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

I think it does not recognize @> despite native query, do you have an idea? 我认为它不承认@>尽管本机查询,你有什么想法吗?

With PostgreSQL and JSON you'll probably run into needing ? 使用PostgreSQL和JSON你可能会遇到需要? or other strange operators, so it's better you just use their function equivalents, instead. 或者其他奇怪的操作符,所以最好只使用它们的功能等价物。 You can look them up in the psql console like this \\doS+ @> . 您可以在psql控制台中查找它们,例如\\doS+ @>

Your query is not native, as the parameter says. 您的查询不是本机的,如参数所示。

select p from Contrat p where...

Will only give you an error when it reaches the database. 只会在到达数据库时给您一个错误。

Try something like 尝试类似的东西

@Query(nativeQuery = true, value = "select * from Contrat where jsonb_contains(contrat_json, :nom )")

and just bind "{\\"nom\\":\\"" + param + "\\"}" as the parameter 并将"{\\"nom\\":\\"" + param + "\\"}"绑定为参数

I had similar problem with my native query. 我的原生查询遇到了类似的问题。 The jsonb field name is called data , and it's simple jsonb字段名称称为数据 ,它很简单

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

I want to find by name with JpaRepository, and here is my Repository 我想通过名字找到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);
}

You need nativeQuery = true . 你需要nativeQuery = true With nativeQuery = true , this works as well. 使用nativeQuery = true ,这也适用。

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

I see your @Transactional annotation, I assume you have the native query on top of application service method. 我看到你的@Transactional注释,我假设你有一个基于应用程序服务方法的本机查询。 Can you try moving all native query's in repository and use JpaRepository, and use the repository method in your application service? 您是否可以尝试在存储库中移动所有本机查询并使用JpaRepository,并在应用程序服务中使用存储库方法? Here is how my application service uses the repository. 以下是我的应用程序服务使用存储库的方式。

public class LookupListServiceImpl implements LookupListService
{
    @Autowired
    LookupListRepository lookupListRepository;

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

}

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

Parameter holders are not understood inside literals: '...:nom...' will contain the characters :nom , not the bound values of nom . 参数持有人不明白里面的文字: '...:nom...'将包含字符:nom ,而不是绑定值nom

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

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

For 9.4: 对于9.4:

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

For 9.3 (and earlier), there is no JSON containment operator (neither the jsonb type). 对于9.3(及更早版本),没有JSON包含运算符(既不是jsonb类型)。

http://rextester.com/AUHP11519 http://rextester.com/AUHP11519

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM