Sunday 6 April 2014

Exception in thread "main" java.lang.UnsupportedOperationException: The user must supply a JDBC connection

I got this error when I tried to persist  a row in the student table. I was using SQL Server 2008 R2 and Hibernate.
Exception in thread "main" java.lang.UnsupportedOperationException: The user must supply a JDBC connection
My hibernate.cfg.xml file is as follows:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
 
   <property name="url">jdbc:sqlserver://MYSERVER:1433;databaseName=MYDB</property>
<property name="username">sa</property>
<property name="password">MYPASSWORD</property>
<property name="driverClassName">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>

<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.generate_statictics">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">create</property>


<mapping class="Student" />
</session-factory>
</hibernate-configuration>

The root cause of this error is  the incorrectly specified property names. Actually I copied the property names from the bean which was used to initialize the data source in spring from some other project. And out of my negligence forgot to check the property names.

Finally I landed with the correct configuration:
 <property name="hibernate.connection.url">jdbc:sqlserver://AXIOM:1433;databaseName=S3H4</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">123</property>
<property name="hibernate.connection.driverClassName">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>


Note that its also OK if you give just connection.url and so on instead of hibernate.connection.url

Saturday 5 April 2014

Cannot insert the value NULL into column 'stateNo', table 'S3H4.dbo.State'; column does not allow nulls. INSERT fails.

I got the following error when trying to persist the State entity using the code - session.persist(state);

Apr 05, 2014 2:25:50 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Cannot insert the value NULL into column 'stateNo', table 'S3H4.dbo.State'; column does not allow nulls. INSERT fails.

I was auto-generating the primary key using the GeneratedValue annotations given below.
@Entity
@Table(name="STATE")
public class State {

@Id
@GeneratedValue
private int stateNo;
 //other properties and their getters and setters.
}

This strategy of auto-generating primary keys worked fine as long as I was using Oracle 11g. As soon as I moved to SQL Server 2008 R2. I got the error message mentioned in red above.

Solution
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="STATE")
public class State {

@Id
@GeneratedValue(generator="stateNoGenerator")
@GenericGenerator(strategy="increment",name="stateNoGenerator")
@Column(name="STATENO",length=10)
private int stateNo;
//other properties and their getters and setters.
}

Adding the GenericGenerator annotation did the trick. Do  note that GenericGenerator is present within org.hibernate.annotations package and not within  javax.persistence package as one would normally expect.
Add the generator attribute in the GeneratedValue annotation specifying the name of the GenericGenerator.

The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)".

I got this exception
The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)".

This is my hibernate.cfg.xml file
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
 
   <mapping class="Student" />
<property name="url">jdbc:sqlserver://MYSERVER:1433;databaseName=MYDB</property>
<property name="username">sa</property>
<property name="password">PASSWORD</property>
<property name="driverClassName">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>

<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.generate_statictics">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">none</property>

</session-factory>
</hibernate-configuration>

This is the stack trace:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.hibernate.MappingException: invalid configuration
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1484)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1425)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1411)
at SQLSERVERTEST.main(SQLSERVERTEST.java:23)
Caused by: org.xml.sax.SAXParseException; lineNumber: 32; columnNumber: 20; The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)".
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.handleEndElement(Unknown Source)
at org.apache.xerces.impl.dtd.XMLDTDValidator.endElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.dom4j.io.SAXReader.read(SAXReader.java:465)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1481)
... 3 more

Solution
Rearrange the contents of the hibernate configuration file and place the mapping element after all the property elements.
Examination of the error message suggests that within session-factory element first only the property element can appear followed by mapping, class-cache or collection-cache, even and finally listeners. If this ordering is not maintained the above exception is thrown.
The correct hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
   
        <property name="url">jdbc:sqlserver://MYSERVER:1433;databaseName=MYDB</property>
<property name="username">sa</property>
<property name="password">PASSWORD</property>
<property name="driverClassName">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.generate_statictics">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">none</property>

<mapping class="Student" />
</session-factory>
</hibernate-configuration>