Intreceptor in spring - spring

I want know about, from where the onsave() method gets arguments?
Example:
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types)

This method should come from hibernate interceptor interface (org.hibernate.Interceptor).Spring may provides some built-in beans that implements this interface .
This method is supposed to be called when an new entity is first saved by the hibernate session. For example , suppose you map the EMPLOYEE table to the employee object and you create a new employee record using the following codes:
Employee employee = new Employee();
employee.setName("Peter");
employee.setJoinDate(new Date());
employee.setExtNumber(1234);
/*seesion refer to the Hibernate session*/
session.save(employee);
Hibernate will then generate the following INSERT SQL :
insert into EMPLOYEE (NAME, JOIN_DATE , EXT_NUMBER) values ("Peter" , to_date('2011-6-20') , 1234)
Before the above SQL is issued to the DB , and if there an interceptor enable , hibernate will call onSave() method with the following parameters:
entity : The employee reference that is being saved
id : PK of the new employee record
state : Arrays containing the values of different fields for the INSERT SQL (i.e. Array
containing the value "Peter" , new Date() , 1234)
propertyNames : Arrays containing the name of the columns for the INSERT SQL (i.e Array containing the string "NAME" , "JOIN_DATE" , "EXT_NUMBER")

Related

How to access PostgreSQL RETURNING value in Spring Boot DAO?

I want to return the auto-generated id of entity. PostgeSQL is able to automaticaly selects certain column via RETURNING, but I have a hard time trying to find how to retrieve this value in Spring Boot.
I would want something like:
public int createUser(User user) {
String sql = "INSERT INTO user (name, surname) VALUES (?,?) RETURNING id";
return jdbcTemplate.update(sql,
user.getName(),
user.getSurname(),
resultSet -> resultSet.getInt("id")
);
}
I know it's straightforward in Hibernate, then whether you use a Repository class or an EntityManager, the save method returns the saved entity, so you can just do:
int id = userRepository.save(user).getId();
Or is there a reason you want to persist it the way you do?

Spring Data JPA passing dynamic column names as parameter to query

I have table emp with columns emp_name, emp_desc, emp_age, emp_country, emp_pincode.
I am using Spring data Jpa for database operations.
#Repository
public interface EmpRepository extends JpaRepository<Emp, String> {}
and empRepository.findAll(); fires a select * from emp table.
But I have a requirement like as follows
The client app would pass column names to select in the method as parameter and I want to fetch only those in Jpa not Findall().
How to acheive this in Jpa?
Try this one
To get the employee details based on emp_name
empRepository.findByEmpName(String empName);

How to Query Cassandra using CassandraRepository with Spring Data Cassandra and Spring Boot?

I have a Table in my Cassandra Cluster built using these commands:
CREATE KEYSPACE IF NOT EXISTS activitylogs WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true;
CREATE TABLE IF NOT EXISTS activitylogs.activities2 (
activity_id timeuuid,
actor_id text,
app_id text,
item_id text,
viewer_id text,
activity_type int,
ts timestamp,
PRIMARY KEY (actor_id, activity_id, app_id)
) WITH CLUSTERING ORDER BY (activity_id DESC, app_id ASC);
This is what my Repository in Spring Project looks like:
public interface ActivityRepository extends CassandraRepository<Activity> {
#Query("SELECT actor_id FROM activities2 WHERE actor_id='actorA'")
Iterable<Activity> findByActor_Id(String actor_Id);
}
Now, when I access the endpoint associated with this query retriever , I get the following error:
Invalid null value in condition for column actor_id
at com.datastax.driver.core.Responses$Error.asException(Responses.java:136)
However, when I run the equivalent CQL command in CQLSHell I get the exact row I was looking for...
Why is this happening ?
There was a mistake in writing the controller for the SpringBoot app.
The proper controller is thus:
#RequestMapping(value = "/activity/{actor_id}",method = RequestMethod.GET)
#ResponseBody
public List<Activity> activity1(**#PathVariable("actor_id")** String actor_id) {
List<Activity> activities = new ArrayList<>();
activityRepository.findByActor_Id(actor_id).forEach(e->activities.add(e));
return activities;
}
Earlier implementation (at the time of writing the question) did not have #PathVariable annotation hence, controller wasn't passing any value to the repository interface function.

what is difference between ResultSetExtractor vs Rowmapper?

I worked on both row mapper and resultset extractor call back interfaces.I found difference i.e.,
1.Row mapper can be processing per row basis.But Resultset extractor we can naviagte all rows and return type is object.
Is there any difference other than above?.How the works Rowmapper internal and return type is list?.
Basic difference is with ResultsetExtractor you will need to iterate through the result set yourself, say in while loop.
This interface provides you processing of the entire ResultSet at once. The implemetation of Interface method extractData(ResultSet rs) will contain that manual iteration code.
See one implementation of ResultsetExtractor
while some callback handlers like RowCallbackHandler, the interface method processRow(ResultSet rs) loops for you.
RowMapper can be used both was for mapping each row, or entire rows.
For entire rows Object (by template method jdbcTemplate.query())
public List findAll() {
String sql = "SELECT * FROM EMPLOYEE";
return jdbcTemplate.query(sql, new EmployeeRowMapper());
}
without casting will work
For individual object (with Template method jdbcTemplate.queryForObject())
#SuppressWarnings({ "unchecked", "rawtypes" })
public Employee findById(int id) {
String sql = "SELECT * FROM EMPLOYEE WHERE ID = ?";
// jdbcTemplate = new JdbcTemplate(dataSource);
Employee employee = (Employee) jdbcTemplate.queryForObject(sql, new EmployeeRowMapper(), id );
// Method 2 very easy
// Employee employee = (Employee) jdbcTemplate.queryForObject(sql, new Object[] { id }, new BeanPropertyRowMapper(Employee.class));
return employee;
}
#SuppressWarnings("rawtypes")
public class EmployeeRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getInt("ID"));
employee.setName(rs.getString("NAME"));
employee.setAge(rs.getInt("AGE"));
return employee;
}
}
Best Use cases:
Row Mapper: When each row of a ResultSet maps to a domain Object, can be implemented as private inner class.
RowCallbackHandler: When no value is being returned from callback method for each row, e.g. writing row to a file, converting rows to a XML, Filtering rows before adding to collection. Very efficient as ResultSet to Object mapping is not done here.
ResultSetExtractor: When multiple rows of ResultSet map to a single Object. Like when doing complex joins in a query one may need to have access to entire ResultSet instead of single row of rs to build complex Object and you want to take full control of ResultSet. Like Mapping the rows returned from the join of TABLE1 and TABLE2 to an fully-reconstituted TABLE aggregate.
ParameterizedRowMapper is used to create complex objects
JavaDoc of ResultSetExtractor:
This interface is mainly used within the JDBC framework itself. A RowMapper is usually a simpler choice for ResultSet processing, mapping one result object per row instead of one result object for the entire ResultSet.
ResultSetExtractor is suppose to extract the whole ResultSet (possibly multiple rows), while RowMapper is feeded with row at a time.
Most the time, ResultSetExtractor will loop the ResultSet and use RowMapper, snippet example of Spring RowMapperResultSetExtractor:
List<T> results = (this.rowsExpected > 0 ? new ArrayList<T>(this.rowsExpected) : new ArrayList<T>());
int rowNum = 0;
while (rs.next()) {
results.add(this.rowMapper.mapRow(rs, rowNum++));
}
return results;
Pay attention, ALL results will be transformed, this can create Out Of Memory exception.
See also
RowMapperResultSetExtractor
RowMapper: To process one record of ResultSet at a time.
ResultSetExtractor: To process multiple records of ResultSet at a time.
I think one place where a ResultSetExtractor could be advantageous is when you have a result set (like from a call to a stored procedure) and a row mapper, and want to process them like is done under the covers in the jdbcTemplate methods, such as query(String sql, RowMapper rowMapper). In this case you can save yourself from having to manually iterate over the result set by using the ResultSetExtractor instead of just the RowMapper.
For example:
RowMapper
ResultSet resultSet = cs.executeQuery();
int row = 0;
DateRowMapper dateRowMapper = new DateRowMapper();
List<String> dates = new ArrayList<>();
while (resultSet.next()) {
dates.add(dateRowMapper.mapRow(resultSet, ++row));
}
return dates;
ResultSetExtractor
ResultSet resultSet = callableStatement.executeQuery();
return new RowMapperResultSetExtractor<>(new DateRowMapper()).extractData(resultSet);

How to use Spring ColumnMapRowMapper?

Can anyone help me with an example of ColumnMapRowMapper? How to use it?
I've written an answer in my blog, http://selvam2day.blogspot.com/2013/06/singlecolumnrowmapper.html, but here it is for your convenience below:
SingleColumnRowMapper & ColumnMapRowMapper examples in Spring
Spring JDBC includes two default implementations of RowMapper - SingleColumnRowMapper and ColumnMapRowMapper. Below are sample usages of those row mappers.
There are lots of situations when you just want to select one column or only a selected set of columns in your application, and to write custom row mapper implementations for these scenarios doesn't seem right. In these scenarios, we can make use of the spring-provided row mapper implementations.
SingleColumnRowMapper
This class implements the RowMapper interface. As the name suggests, this class can be used to retrieve a single value from the database as a java.util.List. The list contains the column values one per each row.
In the code snippet below, the type of the result value for each row is specified by the constructor argument. It can also be specified by invoking the setRequiredType(Class<T> requiredType) method.
public List getFirstName(int userID)
{
String sql = "select firstname from users where user_id = " + userID;
SingleColumnRowMapper rowMapper = new SingleColumnRowMapper(String.class);
List firstNameList = (List) getJdbcTemplate().query(sql, rowMapper);
for(String firstName: firstNameList)
System.out.println(firstName);
return firstNameList;
}
More information on the class and its methods can be found in the spring javadoc link below.
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jdbc/core/SingleColumnRowMapper.html
ColumnMapRowMapper
ColumnMapRowMapper class can be used to retrieve more than one column from a database table. This class also implements the RowMapper interface. This class creates a java.util.Map for each row, representing all columns as key-value pairs: one entry for each column, with the column name as key.
public List<Map<String, Object>> getUserData(int userID)
{
String sql = "select firstname, lastname, dept from users where userID = ? ";
ColumnMapRowMapper rowMapper = new ColumnMapRowMapper();
List<Map<String, Object>> userDataList = getJdbcTemplate().query(sql, rowMapper, userID);
for(Map<String, Object> map: userDataList){
System.out.println("FirstName = " + map.get("firstname"));
System.out.println("LastName = " + map.get("lastname"));
System.out.println("Department = " + map.get("dept"));
}
return userDataList;
}
More information on the class and its methods can be found in the spring javadoc link below.
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jdbc/core/ColumnMapRowMapper.html

Resources