Migrating to hibernate 5.1.16 from hibernate 4.3 have QuerySyntaxException - java

I'm trying to migrate my hibernate 4.3 to hibernate 5.1.16 and I am ending up with QuerySyntaxException which am not able to figure after one week.
I am using annotation for mapping and I checked my queries all of those uses the same name of my entity class, there is no conflict in the name in my queries which am sure and also the point is it worked with Hibernate 4.3.
All the solution in the web is only pointing to naming conflicts.__Maintence is my first table and the mapping issue is pointing at this table.
Here is my hibernate.cfg which I use for mapping.
<mapping class="wadetech.DB.entity.__Maintenance"/>
This is my __Maintenance class
#Entity
#Table(name = "__maintenance", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
public class __Maintenance implements java.io.Serializable {
This is my __MaintenanceDAO
public Collection<__Maintenance> getMaintenanceByName(String name){
String query = "";
query += "select m from __Maintenance m";
query += " where m.name = :name ";
query += " order by ";
query += " m.startDate desc, m.idMaintenance desc";
return super.list(query, "name", name);
}
And here is my exception
wadetech.exceptions.InfrastructureException: org.hibernate.hql.internal.ast.QuerySyntaxException: __Maintenance is not mapped [select m from __Maintenance m where m.name = :name order by m.startDate desc, m.idMaintenance desc]
at wadetech.DB.base.BaseDAO.anonymousFindByQuery(BaseDAO.java:267)
at wadetech.DB.base.BaseDAO.findByQuery(BaseDAO.java:255)
at wadetech.DB.base.BaseDAO.list(BaseDAO.java:243)
at wadetech.DB.DAOS.__MaintenanceDAO.getMaintenanceByName(__MaintenanceDAO.java:78)
at com.at.project.utils.runtime.RuntimeModifier.HasExecuted(RuntimeModifier.java:128)
at wadetech.listeners.ModificationScriptStartupListener.contextInitialized(ModificationScriptStartupListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5016)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5528)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: __Maintenance is not mapped [select m from __Maintenance m where m.name = :name order by m.startDate desc, m.idMaintenance desc]
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:79)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:217)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76)
Am also adding a section of my HibernateUtil as I have my doubts this is causing due to some transaction issues which I changed after moving to 5.1
Before I used tx.wasCommitted();
which I can't use anymore as was Committed is omitted in hibernate 5.1 so I changed it to the below code tx.getStatus() == TransactionStatus.COMMITTED
Here is my hibernateUtil
public static void beginTransaction(boolean readOnly) throws InfrastructureException {
try {
if( currentConnectionMode == ConnectionMode.MASTER_SLAVE && readOnly ) {
// it is a readOnly tx
Transaction tx = readOnlyThreadTransaction.get();
if (null == tx || tx.getStatus() == TransactionStatus.COMMITTED || tx.getStatus() == TransactionStatus.ROLLED_BACK) {
tx = getReadOnlySession().beginTransaction();
readOnlyThreadTransaction.set(tx);
}
} else {
Transaction tx = threadTransaction.get();
if (null == tx || tx.getStatus() == TransactionStatus.COMMITTED || tx.getStatus() == TransactionStatus.ROLLED_BACK) {
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
} // end if
} // end try
catch (HibernateException ex) {
WLog.DAOLogger.error("Begin transaction", ex);
throw new InfrastructureException(ex);
} // end catch
}
I want to stick on with hibernate 5.1 and don't want to migrate to hibernate 5.2 as 5.2 uses jdk 8+. I prefer hibernate 5.1 because I strictly need to use jdk 1.7

So finally I solve the above issue was.Even though the exception din't help to point the issue. The real problem was at hibernateUtils.
Before this was how my hiberenate utils for hibernate 4.3.
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
sessionFactory = configuration.configure().buildSessionFactory(serviceRegistry);
and I changed it to
registry = new StandardServiceRegistryBuilder().configure().build();
MetadataSources sources = new MetadataSources(registry);
Metadata metadata = sources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();

Related

Error when retrieving values from MS SQL using Hibernate

I've done a program where I have to retrieve the data from a table in MS SQL. I'm using Hibernate where AbtDebtbyCAN is an Entity class. The connection so far is fine but the only problem I'm facing is printing out data from MS SQL using Annotation Mapping. Debt is the name of the table(the name of the table is in lower case) which is to be mapped with. Below here is the result I want to print it out using Hibernate. Can anybody help me on how to achieve the fetching of data?
debt
id can bdrl_debt excess_ta_debt posting_ref debt_settlement_id debt_settlement_at debt_business_date
11425 1099112400000003 0 200 501728 137 2020-10-13 10:51:50.000 2020-10-13
AbtDebtbyCAN
#Data
#Entity
#Table(name = "debt")
public class AbtDebtbbyCAN implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int debt_id;
#Column(name = "can")
private int debt_can;
#Column(name = "bdrl_debt")
private int bdrl_debt;
#Column(name = "excess_ta_debt")
private int excess_ta_debt;
#Column(name = "posting_ref")
private int posting_ref;
#Column(name = "debt_settlement_id")
private int debt_settlement_id;
#Column(name = "debt_settlement_at")
private DateTime debt_settlement_at;
#Column(name = "debt_business_date")
private Date debt_business_date;
}
AbtCANMapperTest
public class AbtCANMapperTest {
public static void main(String args[]) {
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
Metadata meta = new MetadataSources(ssr).getMetadataBuilder().build();
SessionFactory factory = meta.getSessionFactoryBuilder().build();
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
List abtdebt = session.createQuery("FROM AbtDebtbbyCAN WHERE debt_can=1099112400000003").getResultList();
for (Iterator iterator = abtdebt.iterator(); iterator.hasNext(); ) {
AbtDebtbbyCAN abtcan = (AbtDebtbbyCAN) iterator.next();
System.out.print("debt id: " + abtcan.getDebt_id());
System.out.print("debt can: " + abtcan.getDebt_can());
System.out.print("bdrl debt: " + abtcan.getBdrl_debt());
System.out.print("excess debt: " + abtcan.getExcess_ta_debt());
System.out.print("posting ref: " + abtcan.getPosting_ref());
System.out.print("debt settlement id: " + abtcan.getDebt_settlement_id());
System.out.print("debt settlement at: " + abtcan.getDebt_settlement_at());
System.out.println("debt business date: " + abtcan.getDebt_business_date());
}
tx.commit();
} catch (HibernateException e) {
if (tx != null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Error StackTrace
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.type.SerializationException: could not deserialize
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1542)
at org.hibernate.query.Query.getResultList(Query.java:165)
at AbtMainTestControl.AbtTestObj.AbtCANMapperTest.main(AbtCANMapperTest.java:36)
Caused by: org.hibernate.type.SerializationException: could not deserialize
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:243)
at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:138)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:113)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:29)
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:243)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:329)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:3088)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1907)
at org.hibernate.loader.Loader.hydrateEntityState(Loader.java:1835)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1808)
at org.hibernate.loader.Loader.getRow(Loader.java:1660)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:745)
at org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1044)
at org.hibernate.loader.Loader.processResultSet(Loader.java:995)
at org.hibernate.loader.Loader.doQuery(Loader.java:964)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:350)
at org.hibernate.loader.Loader.doList(Loader.java:2887)
at org.hibernate.loader.Loader.doList(Loader.java:2869)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2701)
at org.hibernate.loader.Loader.list(Loader.java:2696)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1415)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1565)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
... 2 more
Caused by: java.io.StreamCorruptedException: invalid stream header: 0000AC53
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:899)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:357)
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:309)
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:299)
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:218)
... 32 more
Caused by: org.hibernate.type.SerializationException: could not deserialize
> Task :AbtCANMapperTest.main() FAILED
Caused by: java.io.StreamCorruptedException: invalid stream header: 0000AC53
Execution failed for task ':AbtCANMapperTest.main()'.
> Process 'command 'C:/Program Files/Java/jdk1.8.0_241/bin/java.exe'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Not sure what types you are exactly using here, but at least DateTime is not a standard type that is supported by Hibernate. If Hibernate does not know about a type, it tries to flush the value in its serialized form as blob/byte[]. If you would use java.sql.Timestamp, java.util.Calendar or any other type that is supported by Hibernate out of the box, this should work properly.

Hibernate Custom ID generator Exception while deploying to weblogic

I am recently working on a task where I am refactoring an old web project. First I tried to run the project on my local weblogic instance before starting refactoring.
While I try to deploy the application I got a hibernate exception as follows ==>
Caused By: org.hibernate.AnnotationException: Unknown Id.generator: unique-id
at org.hibernate.cfg.BinderHelper.makeIdGenerator(BinderHelper.java:428)
at org.hibernate.cfg.AnnotationBinder.bindId(AnnotationBinder.java:1901)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1279)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:754)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:546)
Truncated. see log file for complete stacktrace
The exception above implying that it couldn't find the id generator named "unique-id" . Then I dig in to the code and see that the id field in the entity is string. and there is a custom ID generator class that is implementing hibernate IdentifierGenerator class where it is calling a db function for generating alphanumeric id for each time it is called. Below is piece of code in the entity class where it defines the type of id generation.
#Id
#Column(name = "ID", nullable = false, length = 18)
#GenericGenerator(name = "unique-id", strategy = "com.common.entity.RowIdGenerator")
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "unique-id")
private String id;
And here is the RowIdGenerator class for generating alphanumeric id.
public class RowIdGenerator implements IdentifierGenerator
{
private final static String SQL_TEXT = "SELECT TCC.F_ROW_ID_GEN FROM DUAL";
#Override
public Serializable generate(SessionImplementor sessionImplemetor, Object object) throws HibernateException
{
return this.getNextNumber(sessionImplemetor);
}
private String getNextNumber(SessionImplementor session)
{
try
{
ResultSet rs = null;
PreparedStatement statement = null;
try
{
statement = session.getBatcher().prepareSelectStatement(SQL_TEXT);
rs = statement.executeQuery();
String nextValue = null;
if (rs.next())
nextValue = rs.getString(1);
if (nextValue == null)
throw new HibernateException("is is null.");
return nextValue;
}
finally
{
if (rs != null)
rs.close();
if (statement != null)
session.getBatcher().closeStatement(statement);
}
} catch (SQLException sqle)
{
throw JDBCExceptionHelper.convert(session.getFactory().getSQLExceptionConverter(), sqle, "could not fetch initial value for increment generator", SQL_TEXT);
}
}
}
What may cause this error? I see that the generator named "unique-id" is defined and annotated. As far as I know there is no error in the code, maybe it is because of the configuration of my local weblogic instance but Any comment and advice would be appreciated.
regards
You can auto generate only number as ids.Auto generation for other types like String is not supported by hibernate

How to convert hql to sql and apply filters on it?

I call this method to convert hql query to sql:
public String toSql(String hqlQueryText) {
if (hqlQueryText != null && hqlQueryText.trim().length() > 0) {
QueryTranslatorFactory translatorFactory = new ASTQueryTranslatorFactory();
SessionFactoryImplementor factory = (SessionFactoryImplementor) sessionFactory;
QueryTranslator translator = translatorFactory.createQueryTranslator(hqlQueryText, hqlQueryText, Collections.EMPTY_MAP, factory, null);
translator.compile(Collections.EMPTY_MAP, false);
return translator.getSQLString();
}
return null;
}
and I have this filter in .hbm.xml file of domain class:
<filter name="userAuthorize" condition="some sql query here" />
but I don't know how I should tell hibernate to apply this filter when converting from hql to sql.
Assume that I call above method like this:
public Session getSession() {
try {
return sessionFactory.getCurrentSession();
}
catch (Exception e) {
}
return sessionFactory.openSession();
}
public List<DomainClass> getAll() {
String hql = " some hql query ";
Session session = getSession();
String sql = toSql(hql);
return session.createSQLQuery(sql).list();
}
Not a great Idea. But maybe It helps.
HQL and SQL have some differences, for instance with join , 'on' is used in SQL and 'with' is used in HQL.
So maybe you can use list of words that are unique to HQL and check for them in your String using
hql.contains("with") or hql.indexOf("with").
It is not the responsibility of the QueryTranslator to apply filters. Also, filters don't get applied to native SQL.
It looks like you just want to execute the HQL query? There is no need to have it translated to SQL first:
public List<DomainClass> getAll() {
String hql = " some hql query ";
return session.createQuery(hql).list();
}

Tried to remove the Entit yManager, but none was set

I am getting run time error in Play Framework 2.5 (Java) :
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.IllegalStateException: Tried to remove the Entit yManager, but none was set.]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:98)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.util.concurrent.CompletionException: java.lang.IllegalStateException: Tried to remove the EntityManager, but none was set.
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:593)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977)
at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:21)
at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:18)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:63)
Caused by: java.lang.IllegalStateException: Tried to remove the EntityManager, but none was set.
at play.db.jpa.JPAEntityManagerContext.pop(JPAEntityManagerContext.java:74)
at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:155)
at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:195)
at play.db.jpa.TransactionalAction.call(TransactionalAction.java:25)
at play.core.j.JavaAction$$anonfun$7.apply(JavaAction.scala:108)
at play.core.j.JavaAction$$anonfun$7.apply(JavaAction.scala:108)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:56)
at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:70)
Below is the code :
#Transactional
public Result logincheck(){
Form<User> loginForm = Form.form(User.class).bindFromRequest();
User user = loginForm.get();
User searchUser = UserDao.findUser(user);
if (searchUser != null){
return ok(homepage.render());
}
return ok(login.render(loginForm));
}
In class UserDao:
public static User findUser(User user){
EntityManager em = jpaApi.em();
TypedQuery<User> query = JPA.em().createQuery("select u.* from [RL].[dbo].[userdetails] u where u.userid = :username and u.password = :password", User.class);
query.setParameter("username", user.userid);
query.setParameter("password", user.password);
try{
return (User) query.getSingleResult();
} catch(NoResultException e){
return null;
}
}
We found this issue while working with play2.5. We fixed it by adding
the persistence.xml file into the project as specified here : Play 2.5 JavaJPA creating a persistence unit
and adding the following in the application.conf:
jpa.default=defaultPersistenceUnit
You are using JPA.em() and jpaApi in the same method. Actually this should be the same entity manager. Starting from play 2.5 the proper way is jpaApi, JPA.em() is deprecated. You should take care to inject jpaApi.
The code may be like this:
public static User findUser(User user) {
JPAApi jpaApi = Play.current().injector().instanceOf(JPAApi.class);
EntityManager em = jpaApi.em();
TypedQuery<User> query = em.createQuery("select u.* from [RL].[dbo].[userdetails] u where u.userid = :username and u.password = :password", User.class);
...
}
You can read more here about dependency injection in Play

JPA & PostgreSQL: How do I call a stored procedure using NamedNativeQuery Annotation

Using Postgresql 8.1, Spring 3.0, Hibernate 3.6.
I have a method that calls a stored procedure that works without using Annotations, essentially it is
....
return (Integer) getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) {
// Query query = em.createNamedQuery("checkZone");
Query query = em.createNativeQuery("select zoneArea from zoneArea(:pId, :zId)");
query.setParameter("pId", p.getId());
query.setParameter("zId", z.getId());
try {
return query.getSingleResult(); // Integer expected
} catch (NoResultException e) {
return 0;
}
}
});
....
How can I do this with Annotations, here's my attempt that does not work.
#NamedNativeQueries({
#NamedNativeQuery(
name = "checkZone",
query = "select zoneArea from zoneArea(:pId, :zId)",
hints = {
#QueryHint(name = "org.hibernate.callable", value = "true")
},
resultSetMapping = "scalar",
resultClass = Integer.class)})
#SqlResultSetMapping(name="scalar",columns=#ColumnResult(name="result"))
#Entity
and here is the Exception
Caused by: org.postgresql.util.PSQLException: This statement does not declare an OUT parameter. Use { ?= call ... } to declare one.
at org.postgresql.jdbc2.AbstractJdbc2Statement.registerOutParameter(AbstractJdbc2Statement.java:1849)
at org.postgresql.jdbc3.AbstractJdbc3Statement.registerOutParameter(AbstractJdbc3Statement.java:1513)
at org.hibernate.dialect.PostgreSQLDialect.registerResultSetOutParameter(PostgreSQLDialect.java:335)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1713)
at org.hibernate.loader.Loader.doQuery(Loader.java:801)
I have working code but would like to get this working with Annotations, any ideas appreciated.

Categories