About hibernate NamedNativeQuery - mysql

I am a newbie in hibernate, I am using #javax.persistence.NamedNativeQuery to resolve my stored proc calls from hibernate to mysql but i am getting errors.
Please help:
My persistent class is:
#Entity
#javax.persistence.NamedNativeQuery(name = "SampleNameQuery", query = "call spS_NamedQuery(?,?)", resultClass = NamedQuery.class)
public class NamedQuery {
#Id
public String name;
#Column
public String value;
}
My mysql stored proc is:
DELIMITER $$
DROP PROCEDURE IF EXISTS `cpgDB`.`spS_NamedQuery`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `spS_NamedQuery`(IN name VARCHAR(255),OUT var_value VARCHAR(255))
BEGIN
SET var_value = (SELECT value FROM NamedQuery WHERE NamedQuery.name = name);
END$$
DELIMITER ;
The main method that is calling this code is as:
public static void main(String[] args) throws Exception {
Transaction trx = null;
Session session = HibernateSessionFactory.getSession();
try {
trx = session.beginTransaction();
org.hibernate.Query query = session.getNamedQuery("SampleNameQuery");
query.setParameter(0,"fsdfsdf");
String value = "";
query.setParameter(1,value);
List objList = query.list();
trx.commit();
} catch (Exception ex) {
trx.rollback();
throw ex;
} finally {
HibernateSessionFactory.closeSession();
}
}
My hibernate config file is as :
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.username">xxxx</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/cpgDB</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="myeclipse.connection.profile">MySQL</property>
<property name="connection.password">xxxxx</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping class="Demo.NamedQuery"/>
</session-factory>
</hibernate-configuration>
On code execution i am getting following error/exception:
Sep 15, 2009 8:54:16 PM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: OUT or INOUT argument 2 for routine cpgDB.spS_NamedQuery is not a variable or NEW pseudo-variable in BEFORE trigger
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.doList(Loader.java:2214)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
at org.hibernate.loader.Loader.list(Loader.java:2090)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:152)
at Demo.TestDrive.main(TestDrive.java:44)
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: OUT or INOUT argument 2 for routine cpgDB.spS_NamedQuery is not a variable or NEW pseudo-variable in BEFORE trigger
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:930)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2864)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1567)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1154)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:679)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1256)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1778)
at org.hibernate.loader.Loader.doQuery(Loader.java:662)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2211)
... 7 more
Please help what is going wrong and help me get it corrected. Also refer me to suitable links where i can learn more about this technique.
Thanks in advance
Ashish

I was unable to find answer to this question, the solution i implemented then was to not use the 'out' field in my stored procedure and return the result of sql query via select command only.
Possibly Hibernate has not fully implemented this feature of returning 'Out' parameters.

Related

Hibernate using C3P0 Works fine on Oracle but does not close connection with MySQL 5.6

I am using Servlet 2.4, Hibernate 4.2.4 Final, c3p0 0.9.2.1, Tomcat 7.0.42, MySQL 5.6 & JSP.
I had completed development using Oracle 11gR2 DB but at a later point was asked to switch to MySQL as the Database.
I have a rather unusual problem at hand.
The problem is Multiple MySQL Process/Connections being created for every single DB request, which are neither closed nor returned to the pool despite issuing the SessionFactoryUtil.close(); which was not the case with Oracle DB.
I tested the exact same code on these two different Databases, i.e after executing a Function/Request (ex: Login)
The application when tested with Oracle (11gR2) the DB created a single connection and used it for all requests henceforth.
SELECT * FROM V$RESOURCE_LIMIT
Gives me the following Output
RESOURCE_NAME: processes
CURRENT_UTILIZATION: 32
MAX_UTILIZATION: 36
INITIAL_ALLOCATION: 300
LIMIT_VALUE: 300
No matter how many users log in the Connection pool maintains it gracefully.
Now on the other hand when the same application was run on MySQL:
I did a SHOW PROCESSLIST; on MySQL which shows two processes being created for every request; c3p0 successfully terminates one connection but the other connection remains till the DB crashes because it exceeded the max connections available.
My SessionFactoryUtil is quite simple and straightforward and is as follows:
public class SessionFactoryUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
return sessionFactory = new Configuration().configure()
.buildSessionFactory();//deprecated method not changed due to official reason
}
public Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
public static void close() {
if (sessionFactory != null) {
sessionFactory.close();
}
sessionFactory = null;
}
My DAO Method is as follows
public User getUserByName(String userName) throws FetchException {
User user = null;
Session session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
try {
session.beginTransaction();
user = (User) session.createQuery("from User where userName = '" + userName + "'").uniqueResult();
} catch (Exception e) {
logger.info("UserDaoImpl -> getUserByName() : Error : " +e);
e.printStackTrace();
} finally {
SessionFactoryUtil.close();
}
return user;
The stack trace where c3p0 destroys a connection is as follows:
20:45:43,692 INFO com.mchange.v2.resourcepool.BasicResourcePool:1493 - A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection#61f31fff
20:45:43,692 INFO com.mchange.v2.resourcepool.BasicResourcePool:1496 - Logging the stack trace by which the overdue resource was checked-out.
java.lang.Exception: DEBUG STACK TRACE: Overdue resource check-out stack trace.
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:555)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:682)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
at org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:84)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at com.sun.proxy.$Proxy7.beginTransaction(Unknown Source)
at com.demo.access.impl.ConfDaoImp.showAllEvents(ConfDaoImp.java:939)
at com.demo.business.impl.ConfServiceImpl.showAllEvents(ConfServiceImpl.java:404)
at com.demo.controller.UserController.getControls(UserController.java:112)
at com.demo.controller.UserController.validateUser(UserController.java:93)
at com.demo.controller.UserController.process(UserController.java:42)
at com.demo.controller.ApplicationServlet.process(ApplicationServlet.java:75)
at com.demo.controller.ApplicationServlet.doPost(ApplicationServlet.java:53)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.demo.controller.LoginFilter.doFilter(LoginFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I have read almost all the question related to this particular scenario but none seems to work, or the thread was abandoned half way, or I am missing out something; could some one please help me get through with this.
This piece of your code did the trick for me:
public static void close() {
if(sessionFactory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)sessionFactory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
}
}
sessionFactory.close(); }
Until then Tomcat had (correctly) complained about memory leaks at each hot deployment. Thanks!
a few ideas:
1) you are never closing the Session you create (implicitly by asking for a "current session"). that's a straightforward reason why you might have an unreturned Connection that eventually times out.
2) you are treating your SessionFactory like a Session, building up then tearing down the whole thing (which includes a Connection pool) just to get and use one Connection. not so good. your SessionFamily should have a long lifecycle, your sessions should be for one-time, short-term use.
Its been a while since I found out the answer to my strange problem and I thought that sharing it would help most.
To start with, A couple of things i did wrong was...
Firstly, I migrated from hibernate 3.6 to 4.2 and on doing so I was still using the deprecated buildSessionFactory() method.
Secondly, I was using SessionFactoryUtil.close() after the end of each query statement in my DAO, which defeats the purpose of using Connection Pooling.
Finally, The strange issue where Oracle seems to close the connection successfully after execution of a statement whereas MySql was unable to close the same still remains a mystery.
This, I suspect happened because I was asking SessionFactoryUtil to close a connection which was originally opened by C3P0ConnectionProvider (which I believe was in-turn causing the connection leaks).
After a lot of research and looking around I re-wrote the SessionFactoryUtil as follows...
public class SessionFactoryUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
public static SessionFactory getSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
public static Session getCurrentSession() {
if(sessionFactory == null){
getSessionFactory();
}
return sessionFactory.getCurrentSession();
}
public static void close() {
if(sessionFactory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)sessionFactory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
}
}
sessionFactory.close();
}
Note that all my connections are opened by C3P0ConnectionProvider so it is only logical to close it using C3P0ConnectionProvider itself.
The following is my hibernate.cfg.xml along with c3p0 settings.
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/application</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="show_sql">true</property>
<property name="format_sql">false</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.connection.release_mode">auto</property>
<!-- Create or update the database schema on startup -->
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- DEPRECATED -->
<!-- <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> -->
<!-- C3p0 connection pooling configuration -->
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="c3p0.unreturnedConnectionTimeout">600</property>
<property name="c3p0.debugUnreturnedConnectionStackTraces">false</property>
<!-- configuration pool via c3p0 -->
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">600</property>
<property name="c3p0.max_size">75</property>
<property name="c3p0.max_statements">5</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.timeout">600</property>
<property name="c3p0.checkoutTimeout">6000000</property>
<property name="c3p0.testConnectionOnCheckout">false</property>
<property name="c3p0.testConnectionOnCheckin">true</property>
<!-- Mapping -->
</session-factory>
This is again one of the methods from my DAO Class...
public User getUserByName(String userName) throws FetchException {
User user = null;
Session session = SessionFactoryUtil.getCurrentSession();
try {
session.beginTransaction();
user = (User) session.createQuery("from User where userName = '" + userName + "'").uniqueResult();
session.getTransaction().commit();
} catch (Exception e) {
logger.info("UserDaoImpl -> getUserByName() : Error : " +e);
e.printStackTrace();
} finally {
}
return user;
Note that in my DAO at the finally block i don't have to close my connection any more I let c3p0 handle the connection pool.
And voila...!! The Application runs!!! Had more than 2000 transaction hits on a single day in a span of 2 hours.
I hope this helps noob hibernate users like me.

Session is closed Exception

I am building an application with Struts 2 hibernate spring 3 with my sql as back end and c3p0 connection pooling(c3p0-0.9.1.1 jar).
Sometimes, when executing a query, I get the below error. When ever I am executing query I check if the connection is closed or not, and if it's closed I will open a new connection before executing the query.
public List<T> find(final Query query, final Object[] values) throws HibernateException, NullPointerException {
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
List<T> resultList = null;
if (hibernateSession == null || !hibernateSession.isOpen()) {
try {
openHibernateSession();
resultList = query.list();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeHibernateSession();
}
} else {
resultList = query.list();
}
return resultList;
}
public List<T> find(final String queryString, final Object[] values) throws HibernateException {
if (hibernateSession == null || !hibernateSession.isOpen()) {
openHibernateSession();
}
Query queryObject = hibernateSession.createQuery(queryString);
return find(queryObject, values);
}
private void openHibernateSession() throws HibernateException {
try {
hibernateSession = HibernateUtil.getSessionFactory().openSession();
hibernateSession.setFlushMode(FlushMode.MANUAL);
hibernateTransaction = hibernateSession.getTransaction();
hibernateTransaction.begin();
} catch (Exception e) {
e.printStackTrace();
}
}
private void closeHibernateSession() {
try {
if (hibernateTransaction != null) {
hibernateSession.flush();
if (!hibernateTransaction.wasCommitted()) {
hibernateTransaction.commit();
}
}
if (hibernateSession != null) {
if (hibernateSession.isOpen()) {
hibernateSession.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/projectdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">50</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.usesTraditionalReflectiveProxies">true</property>
<property name="connection.pool_size">20</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hibernate.connection.isolation">4</property>
you can probably fix your most immediate problem pretty easily. have your closeHibernateSession() reliably set hibernateSession to null. that will force your query functions to create new Sessions rather than try to reuse an old, closed session.
but don't just do this. you have much bigger problems.
you need to be much cleaner in how you organize your hibernate sessions. from the code above, it's clear that you have a member variable called hibernateSession that may be shared by across multiple callers or by multiple queries, that is sometimes null and sometimes not, which various functions lazily initialize but may not close until some time down the line. that's no good at all.
in the simplest arrangement, don't hold the session as a member variable. hold it as a local variable. let openHibernateSession() return a session that will be closed with perfect certainty in a finally block. if for some reason you need sessions to outlive what can be encapsulated by a single function call (which might of course call many other functions, each of which might take the session as a parameter), you will have to be very, very careful. sessions that are open must reliably be close()ed, and you must understand their lifecycles. your current approach, which uses a session if one is already open, but creates a temporary session otherwise, is no good. if you insist on maintaining a Session member variable, you must know with perfect certainty, whenever the member variable will be initialized, exactly how and when it will be close()ed and then reset to null or dereferenced for garbage collection.
you also should understand your transactions, none of this "if i have an uncommitted transaction before close(), commit it."
also, please consider migrating to c3p0-0.9.2.1
When you are trying to save or update a transient instance make sure the entities associated with instance are persistent. This is a common error of users trying to persist a new instance of the entity with the detached references. Get the entity from the persistence context before you set its reference to the transient or detached instance that you are going to persist.

Connecting to a MySQL database from a Spring project

I have been trying to access MySQL routines from my Spring project using SimpleJdbcDaoSupport.
I have a class called AdminSimpleMessageManager, which implements the interface AdminMessageManager.
AdminSimpleMessageManager has an instance of the class AdminSimpleJdbcMessageDao, which implements the interface AdminMessageDao.
AdminSimpleJdbcMessageDao has the following method:
public class AdminSimpleJdbcMessageDao extends SimpleJdbcDaoSupport implements AdminMessageDao {
public int addMessage(String from, String message) {
return getJdbcTemplate().queryForInt("call insert_contact_message(?, ?)", from, message);
}
}
I have included the following in my application context:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/OctagonDB"/>
</bean>
<bean id="adminMessageManager" class="Managers.AdminSimpleMessageManager">
<property name="adminMessageDao" ref="adminMessageDao"/>
</bean>
<bean id="adminMessageDao" class="Managers.dao.AdminSimpleJdbcMessageDao">
<property name="dataSource" ref="dataSource"/>
</bean>
but I feel there are a few important lines missing. I get the error
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/NewWebsite] threw exception [Request processing failed; nested exception is org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [call insert_contact_message(?, ?)]; ResultSet is from UPDATE. No Data.; nested exception is java.sql.SQLException: ResultSet is from UPDATE. No Data.] with root cause
java.sql.SQLException: ResultSet is from UPDATE. No Data.
I am wondering if the SQL routine needs to return some confirmation? Or maybe I am accessing the DB with the wrong information, is there a way of determining whether it even connected?
EDIT:
insert_contact_message looks like this:
CREATE DEFINER=`root`#`localhost` PROCEDURE `insert_contact_message`(
_author VARCHAR(45),
_message MEDIUMTEXT
)
BEGIN
INSERT INTO contact_messages (`author`, `message`, `date_sent`) VALUES (_author, _message, NOW());
END
You're using queryForInt, but insert_contact_message doesn't return a result. I haven't used JdbcTemplate before, but it looks like you might want to use execute that doesn't expect a result set.
Another option is to change from using a procedure to a function.
CREATE DEFINER=`root`#`localhost` FUNCTION `insert_contact_message`(
_author VARCHAR(45),
_message MEDIUMTEXT
)
BEGIN
INSERT INTO contact_messages (`author`, `message`, `date_sent`) VALUES (_author, _message, NOW());
RETURN 1;
END

Hibernate Search Won't return correct results

I built an example project for hibernate search and it works fine without any exception but when I search a string that I have some objects with that string, it returns empty. I don't know what should I do!!! Can somebody help me...
Project is maven based and I use hibernate annotation both for hibernate and hibernate search.
Here 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://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/eprnews
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">***</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<!--
<property name="hibernate.hbm2ddl.auto">create-drop</property>
Hibernate Search -->
<!-- org.hibernate.search.store.FSDirectoryProvider -->
<!-- org.hibernate.search.store.RAMDirectoryProvider for test -->
<!--
<property name="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider</property>
-->
<property name="hibernate.search.default.directory_provider">filesystem</property>
<property name="hibernate.search.default.indexBase">./indexes</property>
<!--
-->
<property name="hibernate.search.worker.execution">async</property>
<property name="hibernate.search.default.optimizer.transaction_limit.max">100</property>
<!-- Mapped classes -->
<mapping class="net.leemoo.test.entity.NewsEntity"/>
</session-factory>
</hibernate-configuration>
and here is my entity:
#Entity
#Table(name="news")
#Indexed
#AnalyzerDef(
name = "PersianAnal",
charFilters = #CharFilterDef(factory = PersianCharFilterFactory.class),
tokenizer = #TokenizerDef(factory = StandardTokenizerFactory.class),
filters={
#TokenFilterDef(factory = ArabicNormalizationFilterFactory.class),
#TokenFilterDef(factory = PersianNormalizationFilterFactory.class)
}
)
public class NewsEntity {
#Id
#GeneratedValue
private Long id;
#Field
#Analyzer(definition="PersianAnal")
private String title;
#Field
#Analyzer(definition="PersianAnal")
private String newsAbstract;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#Analyzer(definition="PersianAnal")
private String content;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#DateBridge(resolution=Resolution.DAY)
private Date creationDate;
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#DateBridge(resolution=Resolution.DAY)
private Date modifiedDate;
private Integer viewsCounter;
#Field
#Analyzer(definition="PersianAnal")
private String keywords;
private Boolean jqueryNews;
private Boolean photoNews;
and setters and getters...
and this is the code that i use for searching:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
FullTextSession fullTextSession = Search.getFullTextSession(session);
try {
// fullTextSession.createIndexer().startAndWait();
QueryBuilder gb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(NewsEntity.class).get();
Query query = gb.keyword().
onFields("title", "newsAbstract", "content").
matching("test").createQuery();
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(query, NewsEntity.class);
List<NewsEntity> result = (List<NewsEntity>)hibQuery.list();
System.out.println(result.size());
} catch (Exception e) {
// e.printStackTrace();
}
session.getTransaction().commit();
session.close();
What should I do? Please help me....
I think I made a silly mistake in that I commented my index creator in last code phrase. I should run it once in the beginning for indexes to be created. I'm sorry again that I took your time.

Hibernate list using cache? -Not updating entity attribute

I have an application that uses hibernate.
I did the following:
Used List to list some entities on database
Logged in my Mysql Database manualy and updated a field in some
entities
Used List again in hibernate doing an identical query as 1
The entity that hibernate listed was not updated.
If I close and open the application. it then shows the entity updated correctly.
Is hibernate using some kind of cache by default?
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/XXX</property>
<property name="hibernate.connection.username">XXXXXXXXXX</property>
<property name="hibernate.connection.password">XXXXXXXXXX</property>
<property name="show_sql">true</property>
Code that lists the entity:
Session s = HibernateUtil.getSession();
Criteria c = s.createCriteria(Solicitacao.class, "s");
//Add some Restrictions here
List<Solicitacao> ls = c.list();
s.close();
My Session factory:
public class HibernateUtil {
private static SessionFactory sessionFactory = null;
static {
// Configurações iniciais de caminho dos diretórios e arquivos
URL url = HibernateUtil.class.getProtectionDomain().getCodeSource().getLocation();
File myFile = null;
try {
myFile = new File(url.toURI());
} catch (Exception ex) {
}
File dir = myFile.getParentFile();
File xml = new File(dir, "hibernate.cfg.xml");
/*
* sessionFactory = new AnnotationConfiguration() .configure("br/com/netradiobrasil/pcp/" +
* "hibernate/hibernate.cfg.xml") .buildSessionFactory();
*/
sessionFactory = new AnnotationConfiguration().configure(xml).buildSessionFactory();
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
I tryed to add those lines in my hibernate.cfg.xml
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
Also tryed to use: session.setCacheMode(CacheMode.IGNORE)
but still didnt solve my problem
Let me guess
After executing this
Session s = HibernateUtil.getSession();
Criteria c = s.createCriteria(Solicitacao.class, "s");
//Add some Restrictions here
List<Solicitacao> ls = c.list();
You changed entries in database manually and then reran the query ? If yes then can you close the session and then rerun your code ?
Adding those lines in my hibernate.cfg.xml - that enables c3p0 fixed my problem
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">40</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">100</property>