当前位置: 首页 > 知识库问答 >
问题:

如何在jpa查询中使用自定义函数?

章海
2023-03-14

我是Spring Jpa和Hibernate的新手。我试图使用一个定制函数从Oracle数据库中获取数据。我可以定义一个实体及其相关的服务、实现和存储库。此外,我通过使用< code>registerFunction创建了一个新的定制Oracle方言,如下所示。

所以我有两个问题:

1)在我的Oracle数据库中,函数位于不同的模式下。我需要指定它的模式吗?如果是的话怎么做?还是hibernate会自动找到?

在提供我的完整堆栈跟踪后,我将在本文末尾提出我的第二个问题...

以下是我的完整堆栈跟踪:

肌动蛋白10gDialect

package blog;

import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;


public class MyOracle10gDialect extends Oracle10gDialect {

    public MyOracle10gDialect() {
        super();
        registerFunction("my_function", new StandardSQLFunction("my_function"));
    }

}

应用程序属性

...
spring.jpa.database-platform=blog.MyOracle10gDialect
...

实体:

package blog.models;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "item", schema = "WOS_SOURCE")
public class WosItem {

    @Id
    @Column(nullable = false)
    private String UT;

    @Column(nullable = false)
    private String TI;

    public String getUT() {
        return UT;
    }

    public void setUT(String UT) {
        this.UT = UT;
    }

    public String getTI() {
        return TI;
    }

    public void setTI(String TI) {
        this.TI = TI;
    }

    public WosItem(String UT, String TI) {
        this.UT = UT;
        this.TI = TI;
    }

    public WosItem() { }

    @Override
    public String toString() {
        return "WosItem{" +
                "UT='" + UT + '\'' +
                ", TI='" + TI + '\'' +
                '}';
    }
}

服务:

package blog.services;

import blog.models.WosItem;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public interface WosItemService {

    List<WosItem> findAll();
    WosItem findById(String id);
    String find_ut(Long ut_seq);
}

实现:

package blog.services;

import blog.models.WosItem;
import blog.repositories.WosItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class WosItemServiceJpaImpl implements WosItemService {

    @Autowired
    private WosItemRepository wosItemRepository;

    @Override
    public List<WosItem> findAll() {
        return this.wosItemRepository.findAll();
    }

    @Override
    public WosItem findById(String id) {
        return this.wosItemRepository.findOne(id);
    }

    @Override
    public String find_ut(Long ut_seq) {
        return this.wosItemRepository.find_ut();
    }
}

存储库:

package blog.repositories;

import blog.models.WosItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;


@Repository
public interface WosItemRepository extends JpaRepository<WosItem, String> {
    @Query("SELECT function('my_function', input) FROM WosItem wos");
    String find_ut();
}

所以在我的Oracle数据库中,我可以使用这个函数,如下所示:

select other_schema.my_function(aa.input) from my_schema.TABLE aa;

例如,假设 aa.input 是332708100009,则返回000332708100009

至于我的第二个问题:

2) 如何在jpa中执行此过程?我知道我的存储库根本不正确。我得到一个类似“此处不允许注释”的错误。我找不到补救办法。

提前致谢。

抛出异常时编辑:

Caused by: java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
 \-[METHOD_CALL] MethodNode: 'function (my_function)'
    +-[METHOD_NAME] IdentNode: 'my_function' {originalText=my_function}
    \-[EXPR_LIST] SqlNode: 'exprList'
       \-[NAMED_PARAM] ParameterNode: '?' {name=ut_seq, expectedType=null}

共有1个答案

松翔
2023-03-14

不幸的是,如果您想在Select语句中使用自定义函数调用的JPA 2.1功能,那么您需要执行一些额外的操作才能使用它。

当您在where语句中使用它时,它无需任何附加操作即可工作,但由于我想在select中为我的一个项目使用它,所以您需要:

1) 扩展Hibernate方言并注册函数:

package com.mypkg.dialect;

import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StringType;

public class CustomOracle10gDialect extends Oracle10gDialect {

    public CustomOracle10gDialect() {
        super();
        registerFunction("my_function"
           , new StandardSQLFunction("my_function", new StringType()));
    }
}

2) 编辑您的Hibernate状态。dialect属性指向该自定义实现:

<property name="hibernate.dialect" value="com.mypkg.dialect.CustomOracle10gDialect"/>

使现代化

如果需要从某个模式调用该函数,则建议这样做:

registerFunction("my_function"
           , new StandardSQLFunction("schema.my_function", new StringType()));

延伸阅读-

 类似资料:
  • 我在这里创建了一个类似于教程的Web应用程序:https://spring.io/guides/tutorials/react-and-spring-data-rest/ . 我已经添加了后gresql数据库,一切正常。我有一个基本查询查找我的存储库中的By用户名(字符串名称),工作正常。我的问题是,由于某种原因我无法创建自定义查询,例如 . 假设我做了一个测试,我只想得到这个语句的值。我说的不能

  • 我有一个整数参数。我需要编写一个定制的Spring JPA查询,其中等效的SQL是<(1,2)中的code>和x.propertyStatuid。 我在SpringDataJPA文档中看到关键字是“in”,如

  • 我想使用@Query批注从具有@OneTo许多关系的实体创建左连接查询。 母公司是: 孩子: 对于DAO,我确实喜欢以下内容: 显然,它是错误的,因为生成的查询是: 选择payment1。uuid为uuid1_9_,付款1_。注册时内部加入付款1的注册金额。uuid=payment1_uid。uuid在哪里注册。效果=? 在生成关系表时: 对我来说,正确的查询应该是这样的: 选择p.*从注册r加入

  • 我正在使用mssql和spring数据JPA,我想通过使用自定义查询注释将新记录插入到表中。 它的给定错误, 原因:组织。冬眠hql。内部的ast。QuerySyntaxException:应为打开,在第1行第23列[插入到客户值(?1,?2)]附近找到“值” 我也试过下面,同样的错误。

  • 问题内容: 我正在使用Spring Data JPA进行项目。我在数据库中有一个表作为my_query。 我想创建一个将字符串作为参数的方法,然后将其作为数据库中的查询执行。 方法: 例如,当我通过 那么它应该在数据库级别运行该查询。 存储库类如下。 但是,它没有按我预期的那样工作。它给出以下错误。 还有什么其他方法可以实现这个目标。提前致谢 问题答案: 您可以参数化的唯一部分是在子句中使用的值。

  • 我是Spring Data投影的新手,我正在尝试在一个新项目中使用此功能。 特别是,我想在与复杂查询关联的回购方法上使用投影。 我用注释注释了我的方法,并声明了一个JPA查询,其中包含几个连接的表/实体和一个复杂的where条件。 在本文中,我了解到可以使用基于接口的投影和基于类的投影,但只有第一个支持嵌套投影。 我需要嵌套投影,但似乎只有使用基于接口的投影才支持此功能,并且这种方法仅适用于自动生