使用Spring @Procedure调用StoredProcedure而不绑定到表

时间:2018-01-30 14:48:00

标签: spring stored-procedures spring-data-jpa spring-repositories

我想知道是否可以调用存储过程而不必将其绑定到表/模型?

在我的情况下,我在数据库中有一个发送邮件的存储过程。我想从Spring那里打电话:

public interface SendEmail extends org.springframework.data.repository.Repository<Email, Long> {
    @Procedure(procedureName = "send_email")
    void sendEmail(String sender, String recipient, String ccRecipient, String subject, String message);
}

上面的代码编译得很好并且运行正常 - 没问题。唯一的问题是我想摆脱extends Repository<Email, Long> - 我该怎么做?如果我只是删除<Email, Long>(因为StoredProcedure没有返回任何内容,因此不需要任何类型):

public interface SendEmail extends org.springframework.data.repository.Repository {
    @Procedure(procedureName = "send_email")
    void sendEmail(String sender, String recipient, String ccRecipient, String subject, String message);
}

然后我收到以下错误:

Caused by: java.lang.IllegalArgumentException: Could not resolve id type of interface x.x.x.x.SendEmail!
    at org.springframework.data.repository.core.support.DefaultRepositoryMetadata.resolveIdType(DefaultRepositoryMetadata.java:81) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.DefaultRepositoryMetadata.<init>(DefaultRepositoryMetadata.java:52) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.AbstractRepositoryMetadata.getMetadata(AbstractRepositoryMetadata.java:71) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepositoryMetadata(RepositoryFactorySupport.java:233) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:260) ~[spring-data-commons-1.13.8.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:101) ~[spring-data-jpa-1.11.8.RELEASE.jar:na]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    ... 41 common frames omitted

如果我删除了extends Repository<Email, Long>并且拥有:

public interface SendEmail {
    @Procedure(procedureName = "send_email")
    void sendEmail(String sender, String recipient, String ccRecipient, String subject, String message);
}

然后我收到以下错误:

Description:

Field sendEmail in x.x.x.EmailService required a bean of type 'x.x.x.SendEmail' that could not be found.


Action:

Consider defining a bean of type 'x.x.x.SendEmail' in your configuration.

作为结论,我需要有一个名为Email的模型,该模型映射到数据库中的表,以便上述工作。为什么会这样?

(我尝试使用@Repositories@Component注释界面

2 个答案:

答案 0 :(得分:1)

Repositories基于存储库的域驱动设计概念:一种对象,其行为类似于聚合根集合,但内容存储在某个持久存储中。因此,Repository需要知道它负责的聚合根以及它的id类型才能在商店中找到它。

对于JPA存储库,这意味着聚合必须是JPA映射的实体。当然可以基于POJO实体实现存储库并由存储过程支持。这个想法没有错,只是它不是一个常见的用例,而且你的用例可能有点过分。

如果您只是想调用存储过程,那么使用简单的Spring bean和JdbcTemplate可能会更好。

答案 1 :(得分:0)

您可以这样使用:

@Repository
public class RepositoryClass implements DataRepository {
    @PersistenceContext
    private EntityManager em;
}