I am working with Spring Boot and Spring Security, but is my first time using Google cloud firebase Firestore, I am connecting to my database via Firebase Admin SDK. I have a configuration class that looks like this.
#Configuration
public class FirestoreUserConfig {
#Bean
public Firestore getDB() {
return FirestoreClient.getFirestore();
}
}
I have BeanCreationException, my stack trace, in summary, looks like this.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getDB' defined in class path resource [com/d1gaming/user/firebaseconfig/FirestoreUserConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.cloud.firestore.Firestore]: Factory method 'getDB' threw exception; nested exception is java.lang.NoClassDefFoundError: com/google/api/gax/rpc/TransportChannelProvider
Caused by: java.lang.ClassNotFoundException: com.google.api.gax.rpc.TransportChannelProvider
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_271]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_271]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) ~[na:1.8.0_271]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_271]
... 105 common frames omitted
The weird thing is I followed Google's documentation on Initializing firebase Admin SDK, I added the corresponding dependencies to my pom.xml file but it does not seem to work anyway. This is my Admin SDK dependency.
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
<version>7.0.1</version>
</dependency>
I imagine Maven is not able to find this TransportChannelProvider class, Im not sure. I also tried adding all of gcp core dependencies in case provided Admin SDK dependency didn't have the class but I had the same result. I am also making use of a Service and a RESTController for my back end application, I don't know if it is relevant to include it here but I am going to include it just in case.
#Service
public class UserService {
public final String USERS_COLLECTION = "users";
#Autowired
private PasswordEncoder passwordEncoder;
private Firestore firestore;
//get users collcetion from Firestore.
private CollectionReference getUsersCollection() {
return firestore.collection(this.USERS_COLLECTION);
}
//Post a user onto the user collection. documentID is auto-generated by firestore.
public String saveUser(User user) throws InterruptedException, ExecutionException {
Query query = getUsersCollection().whereEqualTo("userName", user.getUserName());
QuerySnapshot querySnapshot = query.get().get();
//Query to validate if userName is already in use.
if(querySnapshot.isEmpty()) {
ApiFuture<DocumentReference> document = getUsersCollection().add(user);
DocumentReference reference = document.get();
String userId = document.get().getId();
//Assign auto-generated Id to userId field for ease of querying.
WriteBatch batch = FirestoreClient.getFirestore().batch();
batch.update(reference, "userId",userId);
//ENCODE USER PASSWORD!
batch.update(reference, "userPassword",passwordEncoder.encode(reference.get().get().toObject(User.class).getUserPassword()));
List<WriteResult> results = batch.commit().get();
results.forEach(result -> {
System.out.println("Update Time: " + result.getUpdateTime());
});
return "Created user with ID: " + "'" + userId + "'";
}
return "Username is already in use";
}
//Get User by given its email.
public Optional<User> getUserByEmail(String userEmail) throws InterruptedException, ExecutionException{
Query query = getUsersCollection().whereEqualTo("userEmail", userEmail);
QuerySnapshot snapshot = query.get().get();
//if user with provided Email exists in collection.
if(!snapshot.isEmpty()) {
List<User> userLs = snapshot.toObjects(User.class);
//Since there is a unique email for each document,
//There will only be on User object on list, we will retrieve the first one.
for(User currUser: userLs) {
return Optional.of(currUser);
}
}
return null;
}
//Query for user by given userName.
public Optional<User> getUserByUserName(String userName) throws InterruptedException, ExecutionException{
//Perform a query based on a user's Name.
Query query = getUsersCollection().whereEqualTo("userName", userName);
QuerySnapshot snapshot = query.get().get();
if(!snapshot.isEmpty()) {
List<User> userList = snapshot.toObjects(User.class);
//Since there is a unique userName for each document,
//there will only be one User object on the list, we will retrieve the first one.
for(User currUser: userList) {
return Optional.of(currUser);
}
}
return null;
}
//Query for user by given userName.
public User getUserByName(String userName) throws InterruptedException, ExecutionException {
//Perform a query based on a user's Name.
Query query = getUsersCollection().whereEqualTo("userName", userName);
QuerySnapshot snapshot = query.get().get();
if(!snapshot.isEmpty()) {
List<User> userList = snapshot.toObjects(User.class);
//Since there is a unique userName for each document,
//there will only be one User object on the list, we will retrieve the first one.
for(User currUser : userList) {
return currUser;
}
}
return null;
}
//Get User by its auto-generated ID.
public User getUserById(String userId) throws InterruptedException, ExecutionException {
DocumentReference reference = getUsersCollection().document(userId);
if(reference.get().get().exists()) {
DocumentSnapshot snapshot = reference.get().get();
User user = snapshot.toObject(User.class);
return user;
}
return null;
}
//Get DocumentReference on a User.
public DocumentReference getUserReference(String userId) throws InterruptedException, ExecutionException {
DocumentReference reference = getUsersCollection().document(userId);
//Evaluate if documentExists in users collection.
if(reference.get().get().exists()) {
return reference;
}
return null;
}
//return a list of objects located in the users collection.
public List<User> getAllUsers() throws InterruptedException, ExecutionException {
//asynchronously retrieve all documents
ApiFuture<QuerySnapshot> future = getUsersCollection().get();
List<QueryDocumentSnapshot> objects = future.get().getDocuments();
//If there is no documents, return null.
if(!objects.isEmpty()) {
List<User> ls = new ArrayList<>();
objects.forEach((obj) -> {
User currUser = obj.toObject(User.class);
ls.add(currUser);
});
return ls;
}
return null;
}
//delete a User from users collection by a given id.
//In reality delete method just changes UserStatus from active to inactive or banned.
public String deleteUserById(String userId) throws InterruptedException, ExecutionException {
Firestore db = FirestoreClient.getFirestore();
DocumentReference reference = db.collection(USERS_COLLECTION).document(userId);
User user = reference.get().get().toObject(User.class);
if(user == null) {
return "User not found.";
}
WriteBatch batch = db.batch();
batch.update(reference, "userStatusCode",UserStatus.INACTIVE);
ApiFuture<List<WriteResult>> result = batch.commit();
List<WriteResult> results = result.get();
results.forEach(response -> {
System.out.println("Update Time:" + response.getUpdateTime());
});
//Check if user did actually change status.
if(reference.get().get().toObject(User.class).getStatusCode().equals(UserStatus.ACTIVE)) {
return "User with ID: " + "'" + userId + "'" + " was deleted.";
}
return "User could not be deleted";
}
//Delete a User's certain field value.
public String deleteUserField(String userId, String userField) throws InterruptedException, ExecutionException {
Firestore firestore = FirestoreClient.getFirestore();
DocumentReference reference = getUsersCollection().document(userId);
if(!reference.get().get().exists()) {
return "User not found.";
}
Map<String,Object> map = new HashMap<>();
map.put(userField, FieldValue.delete());
WriteBatch batch = firestore.batch();
batch.update(reference, map);
List<WriteResult> results = batch.commit().get();
results.forEach(response -> System.out.println("Update Time: " + response.getUpdateTime()));
return "Field deleted Successfully";
}
//Change UserStatus to BANNED
public String banUserById(String userId) throws InterruptedException, ExecutionException {
Firestore db = FirestoreClient.getFirestore();
final DocumentReference reference = db.collection(this.USERS_COLLECTION).document(userId);
WriteBatch batch = db.batch().update(reference,"userStatusCode",UserStatus.BANNED);
List<WriteResult> results = batch.commit().get();
results.forEach(response -> System.out.println("Update Time: " + response.getUpdateTime()));
if(reference.get().get().toObject(User.class).getStatusCode().equals(UserStatus.BANNED)) {
return "User with ID: " + "'" + userId + "'" + " was BANNED.";
}
return "User could not be BANNED.";
}
//Set a user with all new fields.
public String updateUser(User user) throws InterruptedException, ExecutionException {
Firestore firestore = FirestoreClient.getFirestore();
final DocumentReference reference = getUsersCollection().document(user.getUserId());
DocumentSnapshot snapshot = reference.get().get();
if(snapshot.exists()) {
WriteBatch batch = firestore.batch();
batch.set(reference, user);
List<WriteResult> results = batch.commit().get();
results.forEach(response -> System.out.println("Update time: " + response.getUpdateTime()));
return "User updated successfully";
}
return "User not found.";
}
// Update a specific field on a given document by another given value. In case userId is field to be changed, one integer will be subtracted from userTokens field.
public String updateUserField(String userId,String objectField, String replaceValue) throws InterruptedException, ExecutionException {
Firestore db = FirestoreClient.getFirestore();
final DocumentReference reference = getUsersCollection().document(userId);
if(!reference.get().get().exists()) {
return "User not found.";
}
WriteBatch batch = db.batch();
List<WriteResult> results = new ArrayList<>();
//These fields cannot be updated.
if(!objectField.equals("userName") && !objectField.equals("userCash") && !objectField.equals("userTokens") && !objectField.equals("userId")) {
batch.update(reference, objectField, replaceValue);
results = batch.commit().get();
results.forEach(response ->{
System.out.println("Update time: " + response.getUpdateTime());
});
}
else if(objectField.equals("userName")) {
String response = updateUserName(userId, replaceValue);
return response;
}
else {
return "This field canntot be updated.";
}
return "User field could not be updated.";
}
//Update a user's userName depending of availability and token adquisition capacity. i.e. if user has enough tokens to pay fee.
public String updateUserName(String userId, String newUserName) throws InterruptedException, ExecutionException {
Firestore db = FirestoreClient.getFirestore();
final DocumentReference reference = getUsersCollection().document(userId);
DocumentSnapshot snapshot = reference.get().get();
if(!snapshot.exists()) {
return "User not found.";
}
Query query = getUsersCollection().whereEqualTo("userName", newUserName);
QuerySnapshot querySnapshot = query.get().get();
//Evaluate if userName is already in use.
String response = "Username is already taken";
if(querySnapshot.isEmpty()) {
//Transaction to get() tokens and update() tokens.
ApiFuture<String> futureTransact = db.runTransaction(transaction -> {
DocumentSnapshot doc = transaction.get(reference).get();
double tokens = doc.getDouble("userTokens");
//evaluate if user holds more than one token
if(tokens >= 1) {
transaction.update(reference, "userTokens", tokens - 1);
transaction.update(reference, "userName", newUserName);
return "Username updated to: '"+ newUserName +"'";
}
else {
throw new Exception("Not enough Tokens");
}
});
response = futureTransact.get();
}
return response;
}
//update user Currency field.
public String updateUserCash(String userId, double cashQuantity) throws InterruptedException, ExecutionException {
Firestore firestore = FirestoreClient.getFirestore();
final DocumentReference reference = getUsersCollection().document(userId);
DocumentSnapshot snapshot = reference.get().get();
String response = "User not found.";
//evaluate if document exists
if(snapshot.exists()) {
ApiFuture<String> futureTransaction = firestore.runTransaction(transaction -> {
Map<String,Object> map = new HashMap<>();
map.put("userCash", FieldValue.increment(cashQuantity));
transaction.update(reference, map);
return "Updated userCash";
});
response = futureTransaction.get();
return response;
}
return response;
}
//Update user Token field.
public String updateUserTokens(String userId, double tokenQuantity) throws InterruptedException, ExecutionException {
Firestore firestore = FirestoreClient.getFirestore();
final DocumentReference reference = getUsersCollection().document(userId);
String response = "User not found.";
//evaluate if user exists on collection.
if(reference.get().get().exists()) {
ApiFuture<String> futureTransaction = firestore.runTransaction(transaction -> {
Map<String,Object> map = new HashMap<>();
map.put("userTokens",tokenQuantity);
transaction.update(reference, map);
return "Updated userTokens";
});
response = futureTransaction.get();
return response;
}
return response;
}
//evaluate if given documentId exists on given collection.
public static boolean isPresent(String userId,String collectionName) throws InterruptedException, ExecutionException {
Firestore db = FirestoreClient.getFirestore();
DocumentReference reference = db.collection(collectionName).document(userId);
ApiFuture<DocumentSnapshot> snapshot = reference.get();
DocumentSnapshot document = snapshot.get();
if(!document.exists()) {
return false;
}
return true;
}
//Evaluate if given document's status corresponds to active.
public static boolean isActive(String userId, String collectionName) throws InterruptedException, ExecutionException {
Firestore db = FirestoreClient.getFirestore();
DocumentReference reference = db.collection(collectionName).document(userId);
ApiFuture<DocumentSnapshot> snapshot = reference.get();
DocumentSnapshot result = snapshot.get();
User user = result.toObject(User.class);
if(user.getStatusCode().equals(UserStatus.ACTIVE)) {
return true;
}
return false;
}
}
My Controller class:
#RestController
#RequestMapping("/userapi")
#CrossOrigin(origins = "http://localhost:4200")
public class UserController {
#Autowired
UserService userServ;
#GetMapping(value = "/users/search",params="userName")
#PreAuthorize("hasRole('PLAYER')")
public ResponseEntity<Object> getUserByName(#RequestParam(value = "userName", required = true)final String userName) throws InterruptedException, ExecutionException{
if(userName == null) {
return new ResponseEntity<>("Invalid Input",HttpStatus.BAD_REQUEST);
}
User user = userServ.getUserByName(userName);
if(user == null) {
return new ResponseEntity<>("User Not Found", HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(user,HttpStatus.OK);
}
#GetMapping("/users")
#PreAuthorize("hasRole('PLAYER')")
public ResponseEntity<List<User>> getAllUsers() throws InterruptedException, ExecutionException{
List<User> ls = userServ.getAllUsers();
if(ls.isEmpty()) {
return new ResponseEntity<List<User>>(ls, HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<User>>(ls, HttpStatus.OK);
}
#DeleteMapping(value = "/users/delete",params="userId")
#PreAuthorize("hasRole('ADMINISTRATOR')")
public ResponseEntity<Object> deleteUserById(#RequestParam(value="userId", required = true)String userId, #RequestParam(required = false, value="userField") String userField) throws InterruptedException, ExecutionException{
if(userField != null) {
String response = userServ.deleteUserField(userId, userField);
if(response.equals("User not found.")) {
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(response, HttpStatus.OK);
}
String response = userServ.deleteUserById(userId);
if(response.equals("User not found.")) {
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(response, HttpStatus.OK);
}
#PutMapping(value = "/users/update")
#PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('PLAYER')")
public ResponseEntity<Object> updateUser(#RequestBody User user) throws InterruptedException, ExecutionException{
String response = userServ.updateUser(user);
if(response.equals("User not found.")) {
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(response, HttpStatus.OK);
}
#PutMapping(value = "/users/update",params="userId")
#PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('PLAYER')")
public ResponseEntity<Object> updateUserField(#RequestParam(required = true, value="userId")String userId, #RequestParam(required = true)String userField, #RequestParam(required = true)String replaceValue) throws InterruptedException, ExecutionException{
String response = userServ.updateUserField(userId, userField, replaceValue);
if(response.equals("User not found.")) {
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
else if(response.equals("This field cannot be updated.")) {
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
I didn't find ANY documentation on this particular problem and that is why I am here, I would be glad if anyone could help me solving this problem. Am I missing something? Anyways thank you for your time, happy coding.
as you said, you are missing the TransportChannelProvider interface and it's implementations. it's not provided in the dependency you added.
try to add this dependency to your POM:
<dependency>
<groupId>com.google.api</groupId>
<artifactId>gax</artifactId>
<version>1.57.0</version>
</dependency>
the interface included there.
After checking my pom.xml and my dependency hierarchies(On Eclipse, found on the toolbar above the console when the pom.xml file is being viewed.), I found I had another dependency on another Spring Boot project that was overriding the one I had on my project, make sure to check all dependencies on different projects as well. The dependency version I had on my other project did not include the classes Spring needed to create a a bean.
Hibernate throws such exception:
org.hibernate.QueryException: Expected positional parameter count: 2, actually detected 0
at org.hibernate.query.internal.QueryParameterBindingsImpl.verifyParametersBound(QueryParameterBindingsImpl.java:270)
at org.hibernate.query.internal.AbstractProducedQuery.beforeQuery(AbstractProducedQuery.java:1309)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1408)
at org.hibernate.query.Query.getResultList(Query.java:146)
at pl.code.dao.PersonDAO.personExists(PersonDAO.java:59)
In this method:
#Override
public boolean personExists(String firstName, String location) {
TypedQuery<Person> query = entityManager.createQuery("Select p FROM Person p WHERE p.firstName = ? and p.location = ?", Person.class);
List<Person> all = query.getResultList();
return all.size() > 0 ? true : false;
}
I'm using Hibernate version 5.2.9.Final.
Any ideas what's wrong?
Please use this as the below example to pass in your paramters
Query q =session.createQuery("select u from User u where u.location=? and u.id in (:user_ids)");
q.setParameter(0, location);
q.setParameterList("user_ids", userIds);
return q.list();
I pass in parameters this way:
#Override
public synchronized boolean addPerson(Person person){
if (personDAO.personExists(person.getFirstName(), person.getLocation())) {
return false;
} else {
personDAO.addPerson(person);
return true;
}
}
and in controller
#RequestMapping(value= "/person", method = RequestMethod.POST)
public ResponseEntity<Void> addPerson(#RequestBody Person person, UriComponentsBuilder builder) {
boolean flag = personService.addPerson(person);
if (flag == false) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/person/{id}").buildAndExpand(person.getPid()).toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
How to convert this to return a jdbcTemplate.batchUpdate?
It needs to be executed to several tables.
#Override
public int delete(int id) {
String sql = "update user set deleted=1 where user_id = ?";
Object[] params = new Object[] { id };
try {
return jdbcTemplate.update(sql, params);
} catch (IncorrectResultSizeDataAccessException e) {
throw new UserNotFoundException("User.not.found");
}
}
#Override
public void delete(List<Integer> ids) {
String sql = "update user set deleted=1 where user_id = ?";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Integer userId = ids.get(i);
ps.setLong(1, userId );
}
#Override
public int getBatchSize() {
return ids.size();
}
});
}
//set input parameters
Map<String,Object> inParams = new HashMap<String,Object>();
inParams.put("Sig",resourceHistoryBean.getId());
List<ResourceHistoryBean> resourceHistoryList= new ArrayList<ResourceHistoryBean>();
// define stored procedure
try{
SimpleJdbcCall readResult = new SimpleJdbcCall(getDataSource())
.useInParameterNames("Sig")
.declareParameters(new SqlParameter("Sig", Types.VARCHAR))
.withProcedureName("SP_ResourceAllocationDtls")
.withSchemaName("hrms")
.returningResultSet("ResourceHistory", new ParameterizedRowMapper<ResourceHistoryBean>() {
public ResourceHistoryBean mapRow(ResultSet rs, int rowNum)
throws SQLException {
ResourceHistoryBean bean = new ResourceHistoryBean();
resourceHistoryBean.setProjectName(rs.getString(RH_PROJECT_NAME));
return bean;
}
});
readResult.compile();
// execute stored procedure
Map<String, Object> out = readResult.execute(inParams);
resourceHistoryList = (List<ResourceHistoryBean>) out.get("ResourceHistory");
Looks like I was able to find an alternative solution to above problem (Parameter passing to stored procedure and use a mapping class as well ):
public List<ResourceHistoryBean> getResourceHistory(final ResourceHistoryBean resourceHistoryBean)throws Exception{
try {
// call stored procedure and pass parameter to it
List resourceHistoryList = getJdbcTemplate().query(
"call hrms.SP_ResourceAllocationDtls(?)",
new Object[] {resourceHistoryBean.getId()}, new HistoryMapper());
return resourceHistoryList;
} catch (Exception e) {
throw e;
} finally {
closeTemplate();
}
}
// mapper class
class HistoryMapper implements RowMapper, IDatabaseConstants {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ResourceHistoryBean resourceHistoryBean = new ResourceHistoryBean();
resourceHistoryBean.setProjectName(rs.getString(RH_PROJECT_NAME));
return resourceHistoryBean;
}
}
I am using Spring persistence framework for my project.
I want to call oracle function or stored procedure from this framework.
Can anybody suggest how can I achieve this.
Please give solution for both * oracle function and *stored procedure.
Thanks.
Assuming you are referring to JdbcTemplate:
jdbcTemplate.execute(
new CallableStatementCreator() {
public CallableStatement createCallableStatement(Connection con) throws SQLException{
CallableStatement cs = con.prepareCall("{call MY_STORED_PROCEDURE(?, ?, ?)}");
cs.setInt(1, ...); // first argument
cs.setInt(2, ...); // second argument
cs.setInt(3, ...); // third argument
return cs;
}
},
new CallableStatementCallback() {
public Object doInCallableStatement(CallableStatement cs) throws SQLException{
cs.execute();
return null; // Whatever is returned here is returned from the jdbcTemplate.execute method
}
}
);
Calling a function is almost identical:
jdbcTemplate.execute(
new CallableStatementCreator() {
public CallableStatement createCallableStatement(Connection con) {
CallableStatement cs = con.prepareCall("{? = call MY_FUNCTION(?, ?, ?)}");
cs.registerOutParameter(1, Types.INTEGER); // or whatever type your function returns.
// Set your arguments
cs.setInt(2, ...); // first argument
cs.setInt(3, ...); // second argument
cs.setInt(4, ...); // third argument
return cs;
}
},
new CallableStatementCallback {
public Object doInCallableStatement(CallableStatement cs) {
cs.execute();
int result = cs.getInt(1);
return result; // Whatever is returned here is returned from the jdbcTemplate.execute method
}
}
);
Simpler way of calling a Oracle function in Spring is subclassing StoredProcedure like below
public class MyStoredProcedure extends StoredProcedure{
private static final String SQL = "package.function";
public MyStoredProcedure(DataSource ds){
super(ds,SQL);
declareParameter(new SqlOutParameter("param_out",Types.NUMERIC));
declareParameter(new SqlParameter("param_in",Types.NUMERIC));
setFunction(true);//you must set this as it distinguishes it from a sproc
compile();
}
public String execute(Long rdsId){
Map in = new HashMap();
in.put("param_in",rdsId);
Map out = execute(in);
if(!out.isEmpty())
return out.get("param_out").toString();
else
return null;
}
}
And call it like this
#Autowired DataSource ds;
MyStoredProcedure sp = new MyStoredProcedure(ds);
String i = sp.execute(1l);
The Oracle function used here just takes in a numeric parameter and returns a numeric paramter.
In my opinion this is one of the easiest approaches:
public class ServRepository {
private JdbcTemplate jdbcTemplate;
private SimpleJdbcCall functionGetServerErrors;
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
this.functionGetServerErrors = new SimpleJdbcCall(jdbcTemplate).withFunctionName("THIS_IS_YOUR_DB_FUNCTION_NAME").withSchemaName("OPTIONAL_SCHEMA_NAME");
}
public String callYourFunction(int parameterOne, int parameterTwo) {
SqlParameterSource in = new MapSqlParameterSource().addValue("DB_FUNCTION_INCOMING_PARAMETER_ONE", parameterOne).addValue("DB_FUNCTION_INCOMING_PARAMETER_TWO", parameterTwo);
return functionGetServerErrors.executeFunction(String.class, in);
}
}
Calling function using NamedParameterJdbcTemplate:
final String query = "select MY_FUNCTION(:arg1, :arg2, :arg3) from dual";
Map<String, Object> argMap = new HashMap<>();
argMap.put("arg1", "value1");
argMap.put("arg2", 2);
argMap.put("arg3", "value3");
final String result = new NamedParameterJdbcTemplate(dataSource)
.queryForObject(query, argMap, String.class);
Calling procedure using JdbcTemplate:
final String query = "call MY_PROCEDURE(?, ?, ?)";
final Object[] args = {"arg1", "arg2", "arg3"};
new JdbcTemplate(dataSource).execute(query, args, String.class);
Calling function using SimpleJdbcCall:
Map<String, Object> inParameters = new HashMap<>();
inParameters.put("arg1", 55); // arg1 value
inParameters.put("arg2", 20); // arg2 value
MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource(inParameters);
BigDecimal result = new SimpleJdbcCall(dataSource)
.withCatalogName("MY_PACKAGE")
.withSchemaName("MY_SCHEMA")
.withFunctionName("MY_FUNCTION")
.executeFunction(BigDecimal.class, mapSqlParameterSource);
Calling procedure using SimpleJdbcCall:
new SimpleJdbcCall(dataSource)
.withCatalogName("MY_PACKAGE")
.withProcedureName("MY_PROCEDURE")
.execute("arg1", arg2);