Bad Sql Grammar exception in JDBC spring - java

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.

Related

JdbcTemplate does not return a proper resultset. Why?

I am making a discussion board with Spring.
I am using JdbcTemplate to populate the articles of the users from the database, but the JdbcTemplate's query method does not return the proper ResultSet. Interestingly, when I copy and paste the SQL query from the code to SQL Developer, it returns the proper results.
The photo that shows the SQL query works,
JdbcTemplate code
public class ForumDao {
private JdbcTemplate template;
public ForumDao(DataSource dataSource) {
template = new JdbcTemplate(dataSource);
}
public Collection<ForumArticle> getArticleList(){
Collection<ForumArticle> list = template.query("SELECT ARTICLE_ID, TITLE, NAME, VIEW_NUM, CREATED_DATE FROM MEMBER, FORUM WHERE MEMBER.ID = FORUM.MEMBER_ID",
new RowMapper<ForumArticle>() {
#Override
public ForumArticle mapRow(ResultSet rs, int rowNum) throws SQLException {
ForumArticle article = new ForumArticle();
System.out.println("completeeeee--------------------------------------------------------------------");
article.setArticleID(rs.getInt("ARTICLE_ID"));
article.setTitle(rs.getString("TITLE"));
article.setName(rs.getString("NAME"));
article.setViewNum(rs.getLong("VIEW_NAME"));
article.setCreatedDate(rs.getTimestamp("CREATED_DATE").toLocalDateTime());
return article;
}
});
System.out.println("-dddddddddddddddddddddddddddddddddddd " + list.size());
return list;
}
}
All the configuration set-up is done properly and I am using Oracle DB. I have another DAO class for user data and its JdbcTemplate works perfectly.
When I run my code, the list.size() returns 0 instead of 4. It does not throw any exception.
What can be the possible solution for this issue?
The following line looks wrong:
article.setViewNum(rs.getLong("VIEW_NAME"));
VIEW_NAME should be VIEW_NUM, no?
What's probably happening is that when the above line executes, the code throws a SQLException due to an unknown column in the result set, which terminates the processing and gives you an empty result.

Storing data from select statement created by stored procedure

I hope the title makes sense.
Let's say I have a stored procedure (in Microsoft SQL Server) which generates a select statement based on some parameters and then executes that select statement on a table. Let's say the table is Users and the select statement returns the first user in the table. The user is has an ID, a fname, and an lname.
How can I store the data that is generated by the select statement?
In eclipse, I want to use Spring and JdbcTemplate, and I'm thinking about using a callable statement. Any ideas?
From the Spring documentation:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html
private class GetSysdateProcedure extends StoredProcedure {
private static final String SQL = "sysdate";
public GetSysdateProcedure(DataSource dataSource) {
setDataSource(dataSource);
setFunction(true);
setSql(SQL);
declareParameter(new SqlOutParameter("date", Types.DATE));
compile();
}
public Date execute() {
// the 'sysdate' sproc has no input parameters, so an empty Map is supplied...
Map<String, Object> results = execute(new HashMap<String, Object>());
Date sysdate = (Date) results.get("date");
return sysdate;
}
}

How to parameterize table name using jdbi query annotations?

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);
}

DBUtils fails to fill fields of a Java Bean

I have a mysql table like this:
CREATE TABLE `sezione_menu` (
`id_sezione_menu` int(11) unsigned NOT NULL AUTO_INCREMENT,
`nome` varchar(256) NOT NULL DEFAULT '',
`ordine` int(11) DEFAULT NULL,
PRIMARY KEY (`id_sezione_menu`)
)ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
I use apache dbutils to query my database, with these methods:
public static List<SezioneMenu> getSezioniMenu() {
String sql = "SELECT * FROM sezione_menu";
try {
QueryRunner qr = new QueryRunner(createDataSource());
ResultSetHandler rsh = new BeanListHandler(SezioneMenu.class);
List<SezioneMenu> sezioni = (List<SezioneMenu>)qr.query(sql, rsh);
return sezioni;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
private static DataSource createDataSource() {
BasicDataSource d = new BasicDataSource();
d.setDriverClassName(DRIVER);
d.setUsername(USERNAME);
d.setPassword(PASSWORD);
d.setUrl(DB_URL);
return d;
}
Now, if i run my application, it doesn't throw exception, but some fields (not all!) of my java bean SezioneMenu are empty (integer field equals zero and string field equals empty string).
This happen also with other tables and beans.
I used this method in the past in another system configuration without problems.
You can fix it in two ways:
As per dbutils doc,
Alias the column names in the SQL so they match the Java names: select social_sec# as socialSecurityNumber from person
Subclass BeanProcessor and override the mapColumnsToProperties() method to strip out the offending characters.
If you are keeping a class like this
public class SezioneMenuBean implements Serializable {
private int idSezioneMenu;
private String nome;
private int ordine;
public SezioneMenuBean() {
}
// Getters and setters for bean values
}
As per first solution write your queries something like this SELECT id_sezione_menu AS idSezioneMenu, name, ordine FROM sezione_menu.
Or
Based on second solution you can use GenerousBeanProcessor which is a subclass of BeanProcessor it ignores underscore & case sensitivity from column name. You don't have to implement your own custom BeanProcessor
GenerousBeanProcessor is available since version 1.6 of commons-dbutils.
Usage:
// TODO initialize
QueryRunner queryRunner = null;
ResultSetHandler<List<SezioneMenuBean>> resultSetHandler =
new BeanListHandler<SezioneMenuBean>(SezioneMenuBean.class, new BasicRowProcessor(new GenerousBeanProcessor()));
// best practice is specifying only required columns in the query
// SELECT id_sezione_menu, name, ordine FROM sezione_menu
final List<SezioneMenuBean> sezioneMenuBeans = queryRunner.query("SELECT * FROM sezione_menu", resultSetHandler);
for (SezioneMenuBean sezioneMenuBean : sezioneMenuBeans) {
System.out.println(sezioneMenuBean.getIdSezioneMenu());
}
I faced the same issue of BeanHandler/BeanHandlerList returning null or 0 for database columns.
As mentioned by #aelfric5578 in the comment, I have updated the Bean class with same names as Database, DBUtils returned values correctly.
Having BeanClass defined like this will solve your problem.
public class SezioneMenuBean{
int id_sezione_menu;
String nome;
int ordine;
public SezioneMenuBean(){
}
// Getters and setters for bean values
}

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;
}
}

Categories

Resources