Hibernate list using cache? -Not updating entity attribute - mysql

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>

Related

Hibernate Connection Leak

i'm kinda new on web dev, i'm a trainee on a company since last year and i have the following problem:
I'm making a web app with JSF2.3 and Hibernate 5.4.2.Final and c3p0 5.4.2.Final. The thing is everytime i run and go for the login page, i need to check if there is an admin user already registered - i make a count on employee's table based on employee's code - and if there isn't any administrator, then i get a list of country states and render a form register menu.
So, i get the session from the sessionfactory.opensession() in mine HibernateUtil.class, do the count and clear/close the session like the snipet:
public Long retornaLong(String query) throws Exception{
Session session = new HibernateUtil().getSession();
try {
return (Long) session.createQuery(query).getSingleResult();
}finally {
session.clear();
session.close();
}
}
then i get the country states list from
#SuppressWarnings("unchecked")
public List<T> retornaList(String query) throws Exception{
Session session = new HibernateUtil().getSession();
try {
return (List<T>) session.createQuery(query).getResultList();
}finally {
session.clear();
session.close();
}
}
but if i keep refreshing the page (#viewscoped), like 15+ times, eventually i'll get too many connection exception, this doesn't happen if i use one session for both queries. I think there's no enough time for the session to close, causing a connection leak. I want to use one session for each query, can someone help me. Thanks a lot.
My hibernate.cfg.xml
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>
<!-- properties -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/vetsnpets?useTimezone=true&serverTimezone=UTC</property>
<property name="hibernate.connection.username">vetsNpets</property>
<property name="hibernate.connection.password">123</property>
<property name="hiberante.show_sql">false</property>
<property name="hiberante.format_sql">false</property>
<property name="hbm2ddl.auto">validate</property>
<property name="current_session_context_class">thread</property>
<!-- C3P0 -->
<property name="hibernate.c3p0.initialPoolSize">3</property>
<property name="hibernate.c3p0.minPoolSize">3</property>
<property name="hibernate.c3p0.maxPoolSize">20</property>
<property name="hibernate.c3p0.maxStatements">100</property>
<property name="hibernate.c3p0.maxStatementsPerConnection">5</property>
<property name="hibernate.c3p0.maxIdleTime">2700</property>
<property name="hibernate.c3p0.maxIdleTimeExcessConnections">600</property>
<property name="hibernate.c3p0.acquireIncrement">1</property>

Retrieve data from spring doesn't work after insert

I have a problem when I insert data in my MySQL database with Spring Data Jpa Module.
The problem is the following:
When I startup my Springapplication I create the database and initialize the data with SpringdataJPA and I see the data inserted in the table. Afterwards i wanna insert some data related to inserted data and only 1 of the 3 records inserted before were found. When i restard the server and i dont recreate the data and search for it with the same method every single record is found. I search for 2 weeks for a solution but didnt find anything. I hope you can help me.
NEWS
I think only in words is hard to understand, so I insert the code behind. jpa.xml with all spring jpa configuration. The 2 entities and the initmethods. hopefully you can find my error.
jpa.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:property-placeholder location="classpath:properties/database/database.properties" />
<!-- Declare a datasource that has pooling capabilities-->
<!-- BoneCP configuration -->
<bean id="SoopDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close" >
<property name="driverClass" value="${database.driver}" />
<property name="jdbcUrl" value="${database.url}" />
<property name="username" value="${database.user}"/>
<property name="password" value="${database.password}"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="5"/>
<property name="partitionCount" value="2"/>
<property name="acquireIncrement" value="5"/>
<!-- <property name="statementsCacheSize" value="100"/> -->
<!-- <property name="releaseHelperThreads" value="2"/> -->
</bean>
<!-- Declare a JPA entityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="persistenceUnitName" value="SoopDbProvider" />
<property name="dataSource" ref="SoopDataSource"/>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.soopproject.main.db</value>
</list>
</property>
</bean>
<!-- Db initialization bean -->
<bean id="databaseinit" class="com.soopproject.main.db.init.DatabaseInitialization" init-method="init"/>
<!-- Declare a transaction manager-->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
Entities:
BaseEntityWithPrimary
#MappedSuperclass
#Data
#EqualsAndHashCode(callSuper = false)
public class SoopBaseEntityWithPrimary implements
Serializable {
#Id
#GeneratedValue
private long id;
}
Language:
#Entity
#Data
#EqualsAndHashCode(callSuper = true)
public class Language extends BaseEntityWithPrimary {
#Column(nullable = false, unique = true)
private String shortname;
#Column(nullable = false)
private String longname;
#ManyToMany(cascade = CascadeType.ALL)
private List<TranslationsShort> languageTranslationsShorts;
}
InitMethods
#Autowired
private UserRepository userrep;
#Autowired
private LanguageRepository langrep;
#Autowired
private ErrorCodesRepository errorrep;
private void initLanguage() {
User systemuser = null;
try {
systemuser = userrep.findUserByUsername("system");
} catch (Exception ex) {
DatabaseException exception = new DatabaseReadException(ex);
exception.writeLog();
}
List<Language> languages = new LinkedList<>();
Language deutsch = new Language();
deutsch.setCreateUser(systemuser);
deutsch.setShortname("DE");
deutsch.setLongname("Deutsch");
Language english = new Language();
english.setCreateUser(systemuser);
english.setShortname("EN");
english.setLongname("English");
Language italiano = new Language();
italiano.setCreateUser(systemuser);
italiano.setShortname("IT");
italiano.setLongname("Italiano");
languages.add(deutsch);
languages.add(italiano);
languages.add(english);
for (Language lang : languages) {
Language l_help = null;
try {
l_help = langrep.findLanguageByShortname(lang.getShortname());
} catch (Exception ex) {
DatabaseException exception = new DatabaseReadException(ex);
exception.writeLog();
}
if (l_help == null)
try {
langrep.saveAndFlush(lang);
} catch (Exception e) {
DatabaseException exception = new DatabaseWriteException(e);
exception.writeLog();
}
}
}
private void initErrorCodes() {
User systemuser = null;
Language de = null;
Language it = null;
Language en = null;
try {
systemuser = userrep.findUserByUsername("system");
} catch (Exception ex) {
DatabaseException exception = new DatabaseReadException(ex);
exception.writeLog();
}
try {
de = langrep.findLanguageByShortname("DE");
} catch (Exception ex) {
DatabaseException exception = new DatabaseReadException(ex);
exception.writeLog();
}
try {
it = langrep.findLanguageByShortname("IT");
} catch (Exception ex) {
DatabaseException exception = new DatabaseReadException(ex);
exception.writeLog();
}
try {
en = langrep.findLanguageByShortname("EN");
} catch (Exception ex) {
DatabaseException exception = new DatabaseReadException(ex);
exception.writeLog();
}
The problem is that after startup the springapplication and set <prop key="hibernate.hbm2ddl.auto">create</prop> in the method initErrorCodes only the line with it = langrep.findLanguageByShortname("IT"); finds the data in database. The other 2 calls return null (de = langrep.findLanguageByShortname("DE"); and en = langrep.findLanguageByShortname("EN");). Then i stop the application and look to the database and all data is inserted in the table Language. When i restart the server with <prop key="hibernate.hbm2ddl.auto">none</prop> then all 3 method calls return the data???!?!?! I dont get it. So for sure it's not a problem of the method call. But I cant find the error.
What do you mean by 1 of 3 were found? Are you querying the data, or accessing a relationship?
It sounds like some sort of caching is occurring. Some JPA providers enable caching by default, check you cache settings, and ensure you are maintaining bidirectional relationships correctly.
https://en.wikibooks.org/wiki/Java_Persistence/Caching
https://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side

smartgwt restdatasource json date validation

I am using Spring 3.2 MVC Controller and a Spring-WS to create a RESTful web-service. The Spring controller accepts an object files an update to the database correctly and then returns JSON to the front-end. The Spring Context is set for message converts for JSON. I have Unit Tests for these, so I know the Spring Controllers are working and are filing data accordingly.
The error, actually a warning, comes when I get the data/JSON back from the web-service:
10:05:08.906[ERROR[Phonebook]10:05:08.902:XRP3:WARN:RestDataSource:restUserDS:restUserDS.userBirthDate:value:-99187200000 failed on validator {type:"isDate",typeCastValidator:true,_generated:true,defaultErrorMessage:"Must be a date."}
com.smartgwt.client.core.JsObject$SGWT_WARN: 10:05:08.902:XRP3:WARN:RestDataSource:restUserDS:restUserDS.userBirthDate: value: -99187200000 failed on validator: {type: "isDate",typeCastValidator: true,_generated: true,defaultErrorMessage: "Must be a date."}
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
at java.lang.Thread.run(Thread.java:662)
So, here is my UserDataSource:
package com.opensource.restful.client.datasource;
import java.util.HashMap;
import java.util.Map;
import com.google.gwt.core.client.JavaScriptObject;
import com.opensource.restful.shared.Constants;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.OperationBinding;
import com.smartgwt.client.data.RestDataSource;
import com.smartgwt.client.data.fields.DataSourceBooleanField;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.DSDataFormat;
import com.smartgwt.client.types.DSOperationType;
import com.smartgwt.client.types.DSProtocol;
import com.smartgwt.client.util.JSOHelper;
import com.smartgwt.client.util.JSON;
public class UserDataSource extends RestDataSource
{
private static UserDataSource instance = null;
public static UserDataSource getInstance()
{
if (instance == null)
{
instance = new UserDataSource("restUserDS");
}
return instance;
}
private UserDataSource(String id)
{
setID(id);
setClientOnly(false);
// set up FETCH to use GET requests
OperationBinding fetch = new OperationBinding();
fetch.setOperationType(DSOperationType.FETCH);
fetch.setDataProtocol(DSProtocol.GETPARAMS);
DSRequest fetchProps = new DSRequest();
fetchProps.setHttpMethod("GET");
fetch.setRequestProperties(fetchProps);
// set up ADD to use POST requests
OperationBinding add = new OperationBinding();
add.setOperationType(DSOperationType.ADD);
add.setDataProtocol(DSProtocol.POSTMESSAGE);
// ===========================================
DSRequest addProps = new DSRequest();
addProps.setHttpMethod("POST");
// addProps.setContentType("application/json");
add.setRequestProperties(addProps);
// set up UPDATE to use PUT
OperationBinding update = new OperationBinding();
update.setOperationType(DSOperationType.UPDATE);
update.setDataProtocol(DSProtocol.POSTMESSAGE);
// ===========================================
DSRequest updateProps = new DSRequest();
updateProps.setHttpMethod("PUT");
// updateProps.setContentType("application/json");
update.setRequestProperties(updateProps);
// set up REMOVE to use DELETE
OperationBinding remove = new OperationBinding();
remove.setOperationType(DSOperationType.REMOVE);
DSRequest removeProps = new DSRequest();
removeProps.setHttpMethod("DELETE");
remove.setRequestProperties(removeProps);
// apply all the operational bindings
setOperationBindings(fetch, add, update, remove);
init();
}
private DataSourceIntegerField userIdField;
private DataSourceBooleanField userActiveField;
private DataSourceTextField usernameField;
private DataSourceTextField passwordField;
private DataSourceTextField firstnameField;
private DataSourceTextField lastnameField;
private DataSourceTextField emailField;
private DataSourceTextField securityQuestion1Field;
private DataSourceTextField securityAnswer1Field;
private DataSourceTextField securityQuestion2Field;
private DataSourceTextField securityAnswer2Field;
private DataSourceDateField birthdateField;
private DataSourceIntegerField positionIdField;
protected void init()
{
setDataFormat(DSDataFormat.JSON);
setJsonRecordXPath("/");
// set the values for the datasource
userIdField = new DataSourceIntegerField(Constants.USER_ID, Constants.TITLE_USER_ID);
userIdField.setPrimaryKey(true);
userIdField.setCanEdit(false);
userActiveField = new DataSourceBooleanField(Constants.USER_ACTIVE, Constants.TITLE_USER_ACTIVE);
usernameField = new DataSourceTextField(Constants.USER_USERNAME, Constants.TITLE_USER_USERNAME);
passwordField = new DataSourceTextField(Constants.USER_PASSWORD, Constants.TITLE_USER_PASSWORD);
firstnameField = new DataSourceTextField(Constants.USER_FIRST_NAME, Constants.TITLE_USER_FIRST_NAME);
lastnameField = new DataSourceTextField(Constants.USER_LAST_NAME, Constants.TITLE_USER_LAST_NAME);
emailField = new DataSourceTextField(Constants.USER_EMAIL, Constants.TITLE_USER_EMAIL);
securityQuestion1Field =
new DataSourceTextField(Constants.USER_SECURITY_QUESTION_1, Constants.TITLE_USER_SECURITY_QUESTION_1);
securityAnswer1Field =
new DataSourceTextField(Constants.USER_SECURITY_ANSWER_1, Constants.TITLE_USER_SECURITY_ANSWER_1);
securityQuestion2Field =
new DataSourceTextField(Constants.USER_SECURITY_QUESTION_2, Constants.TITLE_USER_SECURITY_QUESTION_2);
securityAnswer2Field =
new DataSourceTextField(Constants.USER_SECURITY_ANSWER_2, Constants.TITLE_USER_SECURITY_ANSWER_2);
birthdateField = new DataSourceDateField(Constants.USER_BIRTHDATE, Constants.TITLE_USER_BIRTHDATE);
positionIdField = new DataSourceIntegerField(Constants.USER_POSITION_ID, Constants.TITLE_USER_POSITION_ID);
// positionActiveField = new DataSourceBooleanField(Constants.USER_ACTIVE, Constants.TITLE_USER_ACTIVE);
// positionCodeField;
// positionDescriptionField;
setFields(userIdField, userActiveField, usernameField, passwordField, firstnameField, lastnameField,
emailField, birthdateField, securityQuestion1Field, securityAnswer1Field, securityQuestion2Field,
securityAnswer2Field, positionIdField);
setFetchDataURL(getServiceRoot() + "/userId/{id}"); // works great
setAddDataURL(getServiceRoot() + "/create");
setUpdateDataURL(getServiceRoot() + "/update");
setRemoveDataURL(getServiceRoot() + "/remove"); // works great
}
protected String getServiceRoot()
{
return "rest/users";
}
protected String getPrimaryKeyProperty()
{
return "userId";
}
#Override
protected Object transformRequest(DSRequest dsRequest)
{
System.out.println("UserDataSource: transformRequest: START");
dsRequest.setContentType("application/json");
JavaScriptObject jso = dsRequest.getData();
String jsoText = JSON.encode(jso);
System.out.println("UserDataSource: transformRequest: START: jsoText=" + jsoText);
// ================================================================================
// String strDob = JSOHelper.getAttribute(jso, Constants.USER_BIRTHDATE);
// Date dateDob = JSOHelper.getAttributeAsDate(jso, Constants.USER_BIRTHDATE);
// JSOHelper.setAttribute(jso, Constants.USER_BIRTHDATE, dateDob.getTime());
// System.out.println("UserDataSource: transformRequest: START2: jsoText2=" + jsoText);
// ================================================================================
// get the user position id which comes from the UI
// the name of this field from the UI 'userPositionId'
String userPositionId = JSOHelper.getAttribute(jso, Constants.USER_POSITION_ID);
// create a small JavaScriptObject to be used for the position
// the JSON string would look like {"id":x} x = userPositionId
Map mapPositionId = new HashMap();
mapPositionId.put("id", userPositionId);
JavaScriptObject jsoPositionId = JSOHelper.convertMapToJavascriptObject(mapPositionId);
// This creates the new JSON attribute:
// ... , "position":{"id":x}
JSOHelper.setAttribute(jso, "position", jsoPositionId);
// remove the JSON Attribute: ... , "userPositionId":x
JSOHelper.deleteAttribute(jso, Constants.USER_POSITION_ID);
String s1 = JSON.encode(jso);
System.out.println("UserDataSource: transformRequest: FINISH: s1=" + s1);
return s1;
// return super.transformRequest(dsRequest);
}
protected void transformResponse(DSResponse response, DSRequest request, Object data)
{
System.out.println("UserDataSource: transformResponse: START");
super.transformResponse(response, request, data);
System.out.println("UserDataSource: transformResponse: FINISH");
}
}
I can confirm I am sending data/JSON just fine. I have to make a slight change to add an attribute that I am sending back. And I believe that is the purpose of TransformRequest.
The Spring MVC Controller receiving the Update looks like:
#RequestMapping(value="/update",
method=RequestMethod.PUT,produces="application/json",
headers="content-type=application/json")
public #ResponseBody UserDTO updateUser(#RequestBody UserDTO user)
{
System.out.println("UserController: START: updateUser: user=" + user);
UserEntity userEntity = service.update(user);
UserDTO userDto = Mapping.mappingUser(userEntity);
System.out.println("UserController: FINISH: updateUser: userDto=" + userDto);
return userDto;
}
And I can confirm I am getting a valid UserDTO. When I look at the transformResponse:
System.out.println("UserDataSource: transformResponse: START");
super.transformResponse(response, request, data);
System.out.println("UserDataSource: transformResponse: FINISH");
I get the error on the first println, I haven't even done the super.transformResponse just yet. When I look at the data coming back, this is the JSON I am getting back.
{
"userId":1,
"userActive":true,
"position":{
"id":1,
"active":true,
"code":"ADMIN",
"description":"Administrator"
},
"username":"demo",
"password":"demo",
"otherPassword":null,
"userFirstName":"DemoXXX",
"userLastName":"DemoXXX",
"userEmail":"tom#tomholmes.netXXX",
"userSecurityQuestion1":"Meaning of Life?XXX",
"userSecurityAnswer1":"42XX",
"userSecurityQuestion2":"aaaXX",
"userSecurityAnswer2":"bbbXX",
"userBirthDate":-99100800000,
"contacts":[
{
"contactId":2,
"userId":1,
"prefix":"Mr.",
"firstName":"updated_fn",
"middleName":null,
"lastName":"updated_ln",
"suffix":"Jr.",
"address1":"123 main street",
"address2":"Apt. 456",
"city":"Randolph",
"state":"MA",
"zip":"12345-1234",
"companyId":0,
"enteredBy":0,
"enteredDate":null,
"editedBy":0,
"editedDate":null,
"birthDate":null,
"emails":null,
"phones":null,
"links":null
}
],
"userPositionId":null
}
So ... How do I fix my datasource or transformResponse to remove this warning? The JSON appears to be correct, and the only issue is with the "userBirthDate" when it comes back as a long negative number, I presume the milliseconds from the epoch. Is there some change I can make in the JSON/Jackson Mapper to change how the dates are formatted?
Thanks for any help!
UPDATE 1:
The help provided below was helpful, and now I know this is not a SmartGWT or RestDataSource issue and is strictly with how jackson converts a java.util.Date within an object. The conversion changes dates to a negative long number and should have another format. I am using Spring 3.2 and was using the old Jackson 1.9.14. But now, I upgraded to Jackson 2, and my pom.xml now uses:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.1.4</version>
</dependency>
Within my spring-servlext.xml:
<context:component-scan base-package="com.opensource.restful" />
<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd'T'HH:mm:ssZ"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonHttpMessageConverter"/>
</list>
</property>
</bean>
<mvc:annotation-driven />
I have been Googling for a few hours now and looking for a solution that uses the Jackson2 mapper within the Spring Configuration, and after I make sure I get all the bean definitions correct, the userBirthDate is still coming back as a negative long. I am sure this configuration can be tweaked just a bit to get it the way I want, so the date comes back as the ISO format: yyyy-MM-dd'T'HH:mm:ssZ
Thanks for helping me get closer.
UPDATE 2:
I think I did it. As previously stated, I upgraded to Jackson2 which I understand is already part of Spring 3.2, which is the version of Spring I am using.
The spring-servlet.xml that I am using, and which does work looks like:
<context:component-scan base-package="com.opensource.restful" />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd'T'HH:mm:ssZ"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<ref bean="jsonHttpMessageConverter" />
</list>
</property>
</bean>
I had to add MappingJackson2HttpMessageConverter the second time because, it's referenced in the restTemplate ... but If I could just define it once, that would be fine. So, maybe someone can help me define the spring-servlet.xml better.
Anyway, this change works and as a result the JSON date comes back as:
"userBirthDate":"1966-11-03T00:00:00-0500"
so, that's progress so far.
From the validation error - defaultErrorMessage:"Must be a date"
Since birthdateField is DataSourceDateField, your UserDTO.userBirthDate must be a java.util.Date or similar and have Date getUserBirthDate().
And Constants.USER_BIRTHDATE must be set to "userBirthDate".
If all above is alright, its due to default serialization of java.util.Date object to JSON.
Check following for additional information on that.
http://java.dzone.com/articles/how-serialize-javautildate (Do not use static SimpleDateFormat)
Spring 3.1 JSON date format
jackson2 JSON ISO 8601 date from JodaTime in Spring 3.2RC1
SmartGWT works best when following date format is used (e.g.- 2013-05-09T00:00:00).
yyyy-MM-dd'T'HH:mm:ss
System.out.println() can not be used in SmartGWT/GWT as client side code is converted to JavaScript and run inside the browser, without a JVM.
You probably won't need to use transformResponse() in this case.

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.

Shiro: code-duplication in datasource configuration

I use shiro to implement authentication for my CXF web service. I am using a jdbc-Realm and configured it with the help of an ini-file (attached below). The authentication data is persisted in the same database like the other data I need, but for the rest of the system I use a properties-file (can be found below, too) to provide the connection-information.
Now obviously the data for the datasource in both cases is the same, but I do not seem to find a way to resolve this code duplication. Does anybody more experienced with the development of webapplications have a solution? I could change both, the config of shiro and of the rest of the system, if it would help.
Thanks in advance,
zakum
shiro.ini:
[main]
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.authenticationQuery = SELECT password FROM users WHERE username = ?;
ds = org.postgresql.ds.PGSimpleDataSource
ds.user = postgres
ds.password = password
ds.databaseName = servicedb
ds.serverName = localhost
ds.portNumber = 5432
jdbcRealm.dataSource = $ds
securityManager.realms = $jdbcRealm
service.properties:
db. It looks like:
db.name = servicedb
db.user = postgres
db.password = password
db.url = //localhost:5432/
Use a container like Spring to configure Shiro and your JDBC connections. Then you can pass the dataSource as a reference into the JDBCRealm.
<bean id="dataSourceBean" class="com.apache.commons.dbcp.BasicDataSource>
<property name="driverClassName" value"class for driver"/>
... more setup for the data source ...
</bean>
<bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
<property name="dataSource" ref="dataSourceBean"/>
<property name="permissionsLookupEnabled" value="true"/>
<property name="authenticationQuery" value="SELECT password FROM users WHERE username = ?"/>
</bean>
You could automatically replace tokens during your build process using Ant or Maven (among others).
Here's an example using Ant:
<copy file="shiro.template.ini" tofile="shiro.ini" overwrite="true" />
<replace file="shiro.ini" token="#DB_NAME#" value="servicedb"/>
In the *.template.* files you'd use tokens:
ds.databaseName = #DB_NAME#
which would get replaced with the real values during the build process:
ds.dataBaseName = servicedb
(and it would obviously be better to specify the tokens/values in a configuration file and apply the replacements to a list of files using globbing patterns)
Ant: https://ant.apache.org/manual/Tasks/replace.html
Maven: https://code.google.com/p/maven-replacer-plugin/
Although this is an old question, I had a similar query and I solved it the following way. Hope it will be helpful to others.
Shiro ini can be used to configure any class. For data source, I have written my application specific class as this.
import javax.sql.DataSource;
public class MyConfig
{
private static DataSource dataSource;
public void setDataSource(Object ds)
{
dataSource = (DataSource)ds;
}
public static DataSource getDataSource() // your application will use this method to get data source.
{
return dataSource;
}
}
Now in the ini file, I passed the same datasource reference to both, the jdbc realm and my class.
myConfig = my.package.MyConfig
myConfig.dataSource = $ds