I would like to know if it is possible to call a stored procedure without having to bind it to a Table/Model?
In my case I have a stored procedure in the database that sends a mail. I would like to call this from 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);
}
The above code compiles fine and runs fine - no problem. Only problem is that I would like to get rid of the extends Repository<Email, Long>
- how do I do this? If I just delete the <Email, Long>
(since the StoredProcedure does not return anything and thus no type is needed):
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);
}
Then I get the following error:
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
If I delete extends Repository<Email, Long>
and have:
public interface SendEmail {
@Procedure(procedureName = "send_email")
void sendEmail(String sender, String recipient, String ccRecipient, String subject, String message);
}
then I get the following error:
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.
As a conclusion I need to have a model called Email
that is mapped to a table in the database in order for the above to work. Why is this so?
(I have tried to annotate the interface with @Repositories
and @Component
)
JPA 2.1 introduced @NamedStoredProcedureQuery which can be used to declaratively define the stored procedure call. The stored procedure can use parameters of 4 different modes. IN, OUT, and INOUT can be used to define simple input and output parameters. The REF_CURSOR type can be used to return the result of a query.
Repositories
are based on the Domain Driven Design concept of Repository: An object that behaves similarly to a collection of aggregate roots but with the content stored in some persistent store. Therefore a Repository
needs to know the aggregate root it is responsible for and also it's id type in order to find it in the store.
For JPA Repositories this means the aggregate has to be an entity mapped by JPA. It would certainly be possible to implement Repositories based on POJO entities and backed by stored procedures. Nothing wrong with that idea except that it is not a common use case and for your use case probably overkill.
If you just want to call a stored procedure you are probably better of with a simple Spring bean and a JdbcTemplate
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With