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

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

所以我有两个问题:

1)在我的Oracle数据库中,该函数位于不同的模式下。 我需要指定其架构吗? 如果是这样的话? 或者hibernate会自动找到它吗?

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

这是我的完整堆栈跟踪:

MyOracle10gDialect

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

application.properties

 ... 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 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 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 { @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} 

不幸的是,如果要在Select语句中使用自定义function调用的JPA 2.1function,则需要先执行一些其他操作才能使用它。

当你在where语句中使用它时,它可以在没有任何其他操作的情况下工作,但是因为我想将它用于我在select中的一个项目,就像你一样,你需要:

1)扩展hibernate方言并注册你的function:

 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属性以指向该自定义实现:

  

更新

如果需要从某个模式调用该函数,那么建议:

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

进一步阅读 – > 本机函数调用