Friday, July 31, 2015

Hibernate Exceptions at Run time.


Hibernate Exceptions
1. ConstraintVoilationException
2. DataException
3. GenericJDBCException
4. LockAcquisitionException
5. NestableException                                                  
6. NestableRuntimeException
7. SQLGrammarException

1. ConstraintVoilationException Example :

public ConstraintViolationException(String message,
                                    SQLException root,
                                    String sql,
                                    String constraintName)
Using Struts2with Hibernate
The name of password tags does not match the name of your POJO, this allow the parameter interceptor and model driven interceptor fill your POJO. (Otherwise how struts could guss which field must be put in which property)
So change your tags as (do it for other tags too):
 <s:password name="oldpwd" label="Old Password"/>
 <s:password name="newpwd" label="New Password"/>

How could Hibernate possibly know that a record has a non unique value without actually inserting the record?
If you are doing batch inserts and don't want to rollback the whole transaction and discard the session in case of a ConstraintViolationException (that's what you should do in theory after an exception, see this thread and this previous answer), my suggestion would be to use the StatelessSession API and to catch the ConstraintViolationException

2.  DataException
public DataException(String message,
                     SQLException root)

 To verify the types of the columns against the ones you have declared in the bean as it seems there is a type conversion issue.
Caused by: java.sql.SQLException: The value supplied cannot be converted to BIGINT.
I have noticed that some of the fields are having long, some are Long; which should be OK. But it is nice to use either primitives or references; but not a mix.
As a quick check, I suggest you to check whether retrieving all works without any issue.
hsSession.createQuery("from StdOrgUsersV").list()
If above query also results in the same issue, then it is obviously a data type issue; not due to the Criteria.

In fact, your assumption is right, that the aggregate operation result returns the same datatype in which the attribute is stored. Of course that's why you see the error message "outside valid range": a SMALLINT is between -32768 and 32767 signed, or 0 and 65535 unsigned. 8.0042892E7 is far to large for this data type.

3. GenericJDBCException
ERROR: Field 'pincode' doesn't have a default value
   Exception in thread "main" org.hibernate.exception.GenericJDBCException:    
    could not execute statement at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)

public GenericJDBCException(String string,
                            SQLException root,
                            String sql)

1.       You can issue some sort of "keep alive" type of query (ex: SELECT 1) on the connection every so often to keep it alive. This assumes that it got closed because it was idle.
2.       You can re-open the connection every so often.
3.       If you get a connect closed exception then you can just reopen the connection.
4.       You can use a connection pool which can do the keep-alive and the reconnection for you.Apache's DBCP is a favorite of many.
I recommend the last one. You would use DBCP something like:
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUsername("scott");
ds.setPassword("tiger");
ds.setValidationQuery("SELECT 1"); // this is database specific
ds.setTestWhileIdle(true); // test the connections every so often
ds.setUrl(connectURI);
...
while (!shutdown) {
    Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement();
    ...
    stmt.close();
    // this returns the connection back to the pool instead of really closing
    // the connection
    conn.close();
}
4 . LockAcquisitionException

 I have this method :
mymethod(long id){  
    Person p = DAO.findPerson(id);
     Car car = new Car();
    car.setPerson(p);
    p.getCars().add(car);
     DAO.saveOrUpdate(car);
    DAO.saveOrUpdate(p);
    DAO.delete(p.getCars().get(0));//A person have many cars
}  
Mapping :
Person.hbm.xml
<!-- one-to-many : [1,1]-> [0,n] -->
<set name="car" table="cars" lazy="true" inverse="true">
    <key column="id_doc" />
    <one-to-many class="Car" />
</set>
<many-to-one name="officialCar" class="Car"  column="officialcar_id" lazy="false"/>  
Cars.hbm.xml
<many-to-one name="person" class="Person"
            column="id_person" not-null="true" lazy="false"/>   
This method works well for a single thread, and on multiple threads, gives me an error:
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - WARN - org.hibernate.util.JDBCExceptionReporter - SQL Error: 60, SQLState: 61000 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - ERROR - org.hibernate.util.JDBCExceptionReporter - ORA-00060: deadlock detection while waiting for a resource 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - WARN - org.hibernate.util.JDBCExceptionReporter - SQL Error: 60, SQLState: 61000 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - ERROR - org.hibernate.util.JDBCExceptionReporter - ORA-00060: deadlock detection while waiting for a resource 
02/08/2014 - 5:19:11 p.m. - [pool-1-thread-35] - ERROR - org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session 
org.hibernate.exception.LockAcquisitionException: Could not execute JDBC batch update
AOP Transaction :
<tx:advice id="txAdviceNomService" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
        <tx:method name="getAll*" read-only="true" propagation="SUPPORTS" />
        <tx:method name="find*" read-only="true" propagation="SUPPORTS" />
    </tx:attributes>
</tx:advice>
NB : When i add Thread.sleep(5000) after update, it is ok. But this solution is not clean.
5. NestableException

org.apache.commons.lang.exception.NestableRuntimeException

I'm trying to retrieve the data from the database. When I run the program it shows the error java.lang.ClassNotFoundException: org.apache.commons.lang.exception.NestableRuntimeExceptionI have the json-lib jar file in my WEB-INF --> lib directory, I don't know why it is showing this error for JSONArray.
My code is :
        StringBuilder sb=new StringBuilder(1024);
        sb.append("select * from ").append(uname.trim()).append("vcomments").append(" where itemid=").append(itemId).append(" and albumid=").append(albumId);
        sql=sb.toString();
        stmt = conn.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        //ArrayList<String> CommArray=new ArrayList();
        JSONArray arrayObj=new JSONArray();                //#100
        while(rs.next()){
            Commenter comment = new Commenter();
            comment.setUname(rs.getString("uname").trim());
            comment.setComment(rs.getString("comments").trim());
            arrayObj.add(comment.toString());

            }    
         commentObj=gson.toJsonTree(arrayObj);
         myObj.add("commentInfo", commentObj);
         out.println(myObj.toString());
         rs.close();                                                         
         stmt.close();                                                            
         stmt = null;                                                         
         conn.close();                                                            
         conn = null;                                                  
      }                 
And the console output is :
 SEVERE: Servlet.service() for servlet [VComment] in context with path [/skypark] threw exception [Servlet execution threw an exception] with root cause
java.lang.ClassNotFoundException:
 org.apache.commons.lang.exception.NestableRuntimeException
 
6. NestableRuntimeException
I have following maven dependency in my pom.xml:
<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.3.Final</version>
        </dependency>
But after project compile I see following message:
cannot find symbol
  symbol:   class NestableRuntimeException
  location: package org.hibernate.exception

7. SQLGrammarException

org.hibernate.exception.SQLGrammarException:

Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [com.sample.Person]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)

But I already have a table by the name person in the database and here's my modified hibernate.cfg.xml
    <!-- hibernate dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost/testDB</property>
    <property name="hibernate.connection.username">postgres</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.show.sql" ></property> 
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
    <!-- Automatic schema creation (begin) === -->
    <property name="hibernate.hbm2ddl.auto">create</property>
   <!-- Simple memory-only cache -->
    <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- ############################################ -->
    <!-- # mapping files with external dependencies # -->
    <!-- ############################################ -->
    <mapping resource="com/sample/Person.hbm.xml" />
</session-factory>
It would be great if anyone could point out what Im doing wrong, as this is my first attempt at Hibernate. Thanks!
EDIT: Person.hbm.xml
<class name="com.sample.Person" table="person">
     <id name="id" column="ID">
        <generator class="native" />
    </id>
     <property name="name">
        <column name="NAME" length="16" not-null="true" />
    </property>
     <property name="surname">
        <column name="SURNAME" length="16" not-null="true" />
    </property>
     <property name="address">
        <column name="ADDRESS" length="16" not-null="true" />
    </property>
 </class>

I have a Mysql 5.0 database and made classes from entities. Two of them:
@Entity
@Table(name="products")
@NamedQuery(name="Product.findAll", query="SELECT p FROM Product p")
public class Product implements Serializable {
    private static final long serialVersionUID = 1L;
     @Id
    @GeneratedValue
    private Long idProduct;
     @OneToOne()
//  @JoinTable(name="Tblmodeli")
//  @JoinColumn(name="idModel") These two lines are important
     @NotFound(action = NotFoundAction.EXCEPTION)
    private Model idmodel;
     public Long getidProduct() {
        return this.idProduct;
    }
     public void setidProduct(Long idProduct) {
        this.idProduct= idProduct;
    }
public Model getIdmodel() {
        return this.idmodel;
    }
     public void setIdmodel(Model idmodel) {
        this.idmodel = idmodel;
    }
}
The second table:
@Entity
@Table(name="model")
@NamedQuery(name="model.findAll", query="SELECT t FROM model t")
public class Model implements Serializable {
    private static final long serialVersionUID = 1L;
     @Id
    @GeneratedValue
    @Column(name="idModel")
    private Long idModel;
 private String name;
     public Long getIdModel() {
        return this.idModel;
    }
     public void setIdModel(Long idModel) {
        this.idModel = idModel;
    }
      public String getName() {
        return this.name;
    }
     public void setName(String name) {
        this.name= name;
    }
}
persistance.xml
<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    <persistence-unit name="SomeName" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/mydb/</jta-data-source>
<class>model.Products</class> 
<class>model.Model</class>
<property name="hibernate.format_sql" value="true"/>
<property name="use_sql_comments" value="true"/>
<property name="hibernate.show_sql" value="true"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql"/>
<property name="hibernate.max_fetch_depth" value="4"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://MyLink"/>
<property name="javax.persistence.jdbc.user" value="username"/>
<property name="javax.persistence.jdbc.url.password" value="password"/>
When I make this command
Product p=  em.find(Product.class, 1L);
String s=p.getIdmodel().getName();
I become this in console:
  select
product0_.IDNormativa as idProduct1_806_,
product0_.idmodel_idModel as idmodel59_806_
 from
 products product0_ 
where
product0_.productID = '1'

12:19:38,293 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-2) SQL Error: 1054, SQLState: 42S22
12:19:38,293 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-2) Unknown column 'product0_.idmodel_idModel' in 'field list'
12:19:38,294 INFO  [stdout] (http-localhost-127.0.0.1-8080-2) javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Unknown column 'product0_.idmodel_idModel' in 'field list'
When i Uncomment this two lines // @JoinTable(name="Tblmodeli") // @JoinColumn(name="idModel") I become this:
  select
product0_.IDNormativa as idProduct1_806_,
product0_.idmodel_idModel as idmodel59_806_
 from
 products product0_ 
left outer join
Model product0_1_ 
on product0_.idProduct=product0_1_.idProduct
//In this line i need  on product0_.idmodel=product0_1_.idModel
    where
    product0_.idProduct= '1'
12:27:35,546 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-1) SQL Error: 1054, SQLState: 42S22
12:27:35,546 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-1) Unknown column 'product0_1_.idProduct' in 'on clause'
12:27:35,547 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Unknown column 'product0_1_.idProduct' in 'on clause'
I have tried these dialects:
<!--<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>  -->
<!--<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2008Dialect"/>  -->
<!--<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/> -->
I have mysql-connector-5.1.17.jar The project is deployed on Jboss AS 7.1.1 I made some OneToOne and OneToMany in same project and all of them are working except this and few mnore... In the JBOSS folder i have the connector and in the standalone.xml the database and connector
<datasources>
   <datasource jta="true" jndi-name="java:/mydb/" pool-name="my_pool" enabled="true" use-java-context="true" use-ccm="true">
          <connection-url>jdbc:mysql://MyURI</connection-url>
       <driver>mysql</driver>
    <security>
     <user-name>username</user-name>
     <password>password</password>
       </security>
    <statement>
   <prepared-statement-cache-size>100</prepared-statement-cache-size>
          <share-prepared-statements>true</share-prepared-statements>
    </statement>
     </datasource>
   <drivers>
        <driver name="mysql" module="com.mysql"/>
         <driver name="h2" module="com.h2database.h2">
            <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
       </driver>
      </drivers>
    </datasources>

Q. How could Hibernate possibly know that a record has a non unique value without actually inserting the record?
Answer :  If you are doing batch inserts and don't want to rollback the whole transaction and discard the session in case of a ConstraintViolationException (that's what you should do in theory after an exception, see this thread and this previous answer), my suggestion would be to use the StatelessSession API and to catch the ConstraintViolationException.
Hibernate can't do this. You can however do it yourself. Essentially there are two options:
1.      Check for duplicates before insert; or
2.      Catch the ConstraintViolationException and then make sure that the violation is due to a duplicate (since there can be other reasons, like null fields).
The former has the disadvantage that you are checking for duplicates on every insert when the likelihood of there actually being a duplicate may be low. The latter will be faster for usual case where no duplicates occur, but has the disadvantage that you need to check for duplicates after the face. When a ConstraintViolationException is thrown it invalidates the current session; this means you will need to flush before doing a search of a duplicate.
Checking for duplicates before insert is probably the cleanest approach unless there is a major performance problem that you need to worry about. Make sure you do the Lookup and insert in a transaction to ensure that someone doesn't add a duplicate between the lookup and insert, otherwise you will get a ConstraintViolationException.



6 comments:

  1. Thanks for sharing this informative content , Great work
    Leanpitch provides online training in Agile coach during this lockdown period everyone can use it wisely.
    Certified agile coaching Bangalore

    ReplyDelete
  2. Thanks for sharing this informative content , Great work
    Creative Thinking for creating an impact!
    Product Thinking Community introduces PT Labs powered by Leanpitch
    Product thinking conference

    ReplyDelete
  3. Thanks for sharing this informative content , Great work
    Leanpitch provides online training in Product prototyping during this lockdown period everyone can use it wisely.
    icp-cat training

    ReplyDelete
  4. Thanks for sharing this informative content , Great work
    To crack scrum master interview : Scrum Master Interview Questions

    ReplyDelete
  5. Thanks for sharing this informative content , Great work
    Leanpitch provides online training in ICP CAT during this lockdown period everyone can use it wisely.
    ICP-CAT certification

    ReplyDelete
  6. I might want to thank you for the endeavors you have made in composing this article. I am trusting the same best work from you later on too..  6 feet

    ReplyDelete

Java 9 and Java11 and Java17, Java 21 Features

 Java 9 and Java11 and Java17 features along with explanation and examples in realtime scenarios Here's a detailed breakdown of Java 9, ...