How to parameterize table name using jdbi query annotations? - java

The below gives an error. And all my searching indicates that the table name needs to be hardcoded. But possibly there is some clever workaround I couldn't find?
public interface MyDao {
#SqlQuery("INSERT INTO :tbl (ID) VALUES (:id)")
void logInserts1817(#Bind("tbl") String tbl, #Bind("id") String id);
}

Related

Persist object directly to db using mybatis

I am new to mybatis. Previously I used Hibernate ORM framework.Now I want to use mybatis for development.
Below is my mapper class where I can write the actual query for application.
public interface UserMapper {
#Insert("INSERT into user(id,name,address) VALUES(#{uid}, #{uname}, #{uaddress})")
void insertUser(User user);
}
I am getting the User information in request from front end application.
Below is my Controller::
#RequestMapping(value = "/userdetails", method = RequestMethod.POST, headers = "Accept=application/json")
public #ResponseBody ResponseCodeModel userInfo(#RequestBody User user)
{
session.save(user);//In Hibernate
}
If I used Hibernate I can directly persist the user object in db using session.save(userObject);
But in Mybatis ,I need to map all the user parameter in mapper query.
If my table having 50 coloumn then I need to mention all the parameter in query like below::
public interface UserMapper {
#Insert("INSERT into user(id,name,address,....50 Coloumn name) VALUES(#{uid}, #{uname}, #{uaddress} ,....50 model attribute name)")
void insertUser(User user);
}
Is there any easier way to persist the Model Object in DB using myBatis.
Mybatis is SQL Mapper, not ORM. then you indeed have to map.
If you insert into all columns in the table then you may omit the columns name and specify values in right order, this is common SQL.

hibernate #Formula about 'convert(date)'

I am Using SqlServer 2012 and my Entity is
public class Something {
private Date rq;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "rq")
#Formula("CONVERT(DATE,rq)")
public Date getRq() {
return Rq;
}
public void setRq(Date rq) {
this.Rq = rq;
}
}
Hibernate debug log :
Hibernate:
select
CONVERT(dnypowergr0_.DATE,
dnypowergr0_.rq) as formula0_
from
db.dbo.something dnypowergr0_
I want to get the result of 'rq' that can truly 'convert' but as the log shows, the first argument of 'convert' was added an alias of the table, So this sql is error.
Have I written wrong code or used part of '#Formula' ?
Not sure how to make hibernate to do not insert table alias where it is not needed. But there is a workaround.
You can define a transient attribute (something like convertedRq) and convert value in Java. In this case rq will contain pure value of rq field, convertedRq will be calculated on fly.
Update: solution was posted here Hibernate #formula is not supportinng Cast() as int for teradata database :
public class Oracle10gDialectExtended extends Oracle10gDialect {
public Oracle10gDialectExtended() {
super();
/* types for cast: */
registerKeyword("int");
// add more reserved words as you need
}
}
(c) Sergio M C Figueiredo

Spring Data JPA - exception when using findAll with MySQL

I have an entity, and the DAO with interface JpaRepository<MyEntity, Long>. Using EclipseLink.
I'm using the following method from the DAO:
Iterable<MyEntity> findAll(Iterable<Long> ids);
in this way:
List<Long> listOfIds = Arrays.asList(new Long[] {1,2,3});
Iterable<MyEntity> entities = dao.findAll(listOfIds);
I've got the MySQL exception:
java.sql.SQLException: Operand should contain 1 column(s)
The SQL query that is executed in the database has the following syntax:
SELECT id, creation_date, column1, column2 FROM my_entity WHERE (id IN ((1,2,3)))
The problem is in the last braces - there are too many of them. The working query is:
SELECT id, creation_date, column1, column2 FROM my_entity WHERE (id IN (1,2,3))
Any reason why the Spring Data adds these unnecessary braces? Any way to fix it?
FOUND WORKAROUND
First of all, your DAO must also implement the JpaSpecificationExecutor<MyEntity>.
Then, create a Specification-factory class like this:
public final class MyEntitySpecifications {
public static Specification<MyEntity> idsIn(final Collection<Long> ids) {
return new Specification<MyEntity>() {
#Override
public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return root.get("id").in(ids);
}
};
}
}
and use your DAO like this:
Iterable<MyEntity> entities = dao.findAll(MyEntitySpecifications.idsIn(listOfIds));
Produced query is now as expected.

jpa non managed entities

Let's say I have to fire a query like this:
Select primarykey, columnname, old_value, new_value from first_audit_log;
Select primarykey, columnname, old_value, new_value from second_audit_log;
Select primarykey, columnname, old_value, new_value from third_audit_log; ...so on
audit_log is not mapped as JPA enity to any class and I strictly can't create n number of classes for n number of *_audit_logs.
Using native query feature, how best I can map this to a generic class? Trying to SELECT NEW feature, but not sure... Hence any help is appreciated.
Since your audit logs tables share the same columns, you can create a view that "unifies" those tables and map a single Java class to that view. I believe you can, since you don't need to write updates, I guess.
As an alternative, using native queries would be a good choice.
EDIT:
1) If your audit logs are already views, you can create a view based on other views, if you don't want to create a mapping Java class for each of them. Just remember to add a dummy column that has value 1 if the row comes from the "first" audit log, 2 if it comes from the second, and so on, so you can set them apart.
2) In order to use native queries, assuming your persistence provider is Hibernate, you can do like in this example:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
EntityManager em = emf.createEntityManager();
Session sess = em.unwrap(Session.class); // <-- Use Hibernate-specific features
SQLQuery query = sess.createSQLQuery(
"SELECT AVG(age) AS averageAge, AVG(salary) as averageSalary FROM persons");
query.setResultTransformer(Transformers.aliasToBean(MyResult.class));
MyResult result = (MyResult) query.list().get(0);
where MyResult is declared as follows:
public class MyResult {
private BigDecimal averageAge;
private BigDecimal averageSalary;
public BigDecimal getAverageAge() {
return averageAge;
}
public void setAverageAge(BigDecimal averageAge) {
this.averageAge = averageAge;
}
public BigDecimal getAverageSalary() {
return averageSalary;
}
public void setAverageSalary(BigDecimal averageSalary) {
this.averageSalary = averageSalary;
}
}
and the persons table is like this (MySQL syntax):
CREATE TABLE `persons` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(255) NOT NULL,
`lastname` varchar(255) NOT NULL,
`age` int(11) NOT NULL,
`salary` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
You can easily adapt this example to your needs, just replace persons and MyResult with what you want.
The aliases in the sql query is automatically converted to upper case and its looking for the setter in Upper case as a result org.hibernate.PropertyNotFoundException Exception is thrown. Any suggestions would be greatly appreciated.
For instance, the below statement is looking for the setter ID instead of Id/id (Could not find setter for ID on class Data)
List<Data> result = entityManager.unwrap(Session.class)
.createSQLQuery("Select id as id from table")
.setParameter("day", date.getDayOfMonth())
.setParameter("month", date.getMonthOfYear())
.setParameter("year", date.getYear())
.setResultTransformer(Transformers.aliasToBean(Data.class))
.list();
class Data {
Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

Bad Sql Grammar exception in JDBC spring

I am the getting
org.springframework.jdbc.BadSqlGrammarException:
PreparedStatementCallback; bad SQL grammar [select cid,
clinician-code, password, first-name, last-name from Clinician where
clinician-code= ?]; nested exception is
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown
column 'clinician' in 'field list'
error on the following code, You can also see the Table in the screen shot, except for cid all other attributes are VARCHAR(45)
Row mapper class
public class CClinicianRowMapper implements RowMapper {
#Override
public Object mapRow(ResultSet rs, int line) throws SQLException {
CClinicianResultSetExtractor extractor = new CClinicianResultSetExtractor();
return extractor.extractData(rs);
}
}
Result Extractor Class
public class CClinicianResultSetExtractor implements ResultSetExtractor {
#Override
public Object extractData(ResultSet rs) throws SQLException {
CClinician clinician = new CClinician();
clinician.setCid(rs.getLong("cid"));
clinician.setClinicianCode(rs.getString("clinician-code"));
clinician.setPassword(rs.getString("password"));
clinician.setFirstName(rs.getString("first-name"));
return clinician;
}
}
Class for selecting data from table
public List<CClinician> findClinician(CClinician _clinician) {
// TODO Auto-generated method stub
JdbcTemplate select = new JdbcTemplate(dataSource);
try
{
return select.query("select cid, clinician-code, password, first-name, last-name from Clinician where clinician-code= ?",
new Object[] {_clinician.getClinicianCode()}, new CClinicianRowMapper());
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
I know this is an old thread, but hopefully anyone stumbling across this question will find this answer useful.
I was getting the same exception in my spring app. Based on the output, I thought I had a syntax issue with my query. It turns out that I actually had a syntax error in my mapper method. I came across this issue because I originally created my Product class with different field names than the column names.
public class ProductMapper implements RowMapper<Product> {
public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
Product product = new Product();
product.setProduct_id(rs.getInt("product_id")); //was id. was causing BadSqlGrammarException
product.setProduct_name(rs.getString("product_name")); //was name. was causing BadSqlGrammarException
product.setPrice(rs.getDouble("price"));
product.setQuantity(rs.getInt("quantity"));
return product;
}
}
Once I made the above changes (my fields are named product_id and product_name), my app worked correctly. Just remember that any changes you make to column names or java fields should be made not only to your query statements, but also to your mapper method as well. I see that the OP did this correctly, but I thought it was worth reiterating. I hope someone finds this helpful.
In order to use a dash in the column names, you need to escape them with back ticks.
"SELECT cid, `clinician-code`, password, `first-name`, `last-name`
FROM Clinician
WHERE `clinician-code` = ?"
Check your query syntax properly for missing ; or extra comma (,) . 'Bad SQL Grammar Exception' is related only to syntactical mistake in Sql queries.
I was getting same error in following code while working on Spring JDBC:
String query= "update student set name=?, city=?, where id=?"; // due to extra comma after city=?,
Changed code to
String query= "update student set name=? city=?, where id=?";
Error resolved.

Categories

Resources