org.hibernate.hql.internal.ast.QuerySyntaxException: table is not mapped - java

I have example web application Hibernate 4.3.5 + Derby database 10.10.1.1+ Glassfish4.0 with IDE NetBeans 8.0Beta.
I have the next exception:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:331)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3633)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3522)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:562)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
... 72 more
Form from index.xhtml
<h:panelGrid id="panel1" columns="2" border="1"
cellpadding="5" cellspacing="1">
<f:facet name="header">
<h:outputText value="Add Customer Information"/>
</f:facet>
<h:outputLabel value="First Name:"/>
<h:inputText value="#{customer.firstName}" id="fn"/>
<h:outputLabel value="Last Name:"/>
<h:inputText value="#{customer.lastName}" id="ln"/>
<h:outputLabel value="Email:"/>
<h:inputText value="#{customer.email}" id="eml"/>
<h:outputLabel value="Date of Birth:"/>
<h:inputText value="#{customer.sd}" id="s"/>
<f:facet name="footer">
<h:outputLabel value="#{customer.msg}" id="msg" styleClass="msg"/>
<h:commandButton value="Save" action="#{customer.saveCustomer}">
</h:commandButton>
</f:facet>
</h:panelGrid>
Customer.java
package com.javaknowledge.entity;
import com.javaknowledge.dao.CustomerDao;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.*;
#ManagedBean
#SessionScoped
public class Customer implements java.io.Serializable {
private Integer custId;
private String firstName;
private String lastName;
private String email;
private Date dob;
private String sd, msg, selectedname;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public Customer() {
}
public Customer(String firstName, String lastName, String email, Date dob) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.dob = dob;
}
public String getSd() {
return sd;
}
public void setSd(String sd) {
this.sd = sd;
}
public Integer getCustId() {
return this.custId;
}
public void setCustId(Integer custId) {
this.custId = custId;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "EMAIL")
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "DOB")
public Date getDob() {
return this.dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getSelectedname() {
return selectedname;
}
public void setSelectedname(String selectedname) {
this.selectedname = selectedname;
}
public void saveCustomer() {
try {
Date d = sdf.parse(sd);
System.out.println(d);
this.dob = d;
} catch (ParseException e) {
e.printStackTrace();
}
CustomerDao dao = new CustomerDao();
dao.addCustomer(this);
this.msg = "Member Info Saved Successfull!";
clearAll();
}
public void updateCustomer() {
try {
Date d = sdf.parse(sd);
System.out.println(d);
this.dob = d;
} catch (ParseException e) {
e.printStackTrace();
}
CustomerDao dao = new CustomerDao();
dao.updateCustomer(this);
this.msg = "Member Info Update Successfull!";
clearAll();
}
public void deleteCustomer() {
CustomerDao dao = new CustomerDao();
dao.deleteCustomer(custId);
this.msg = "Member Info Delete Successfull!";
clearAll();
}
public List<Customer> getAllCustomers() {
List<Customer> users = new ArrayList<Customer>();
CustomerDao dao = new CustomerDao();
users = dao.getAllCustomers();
return users;
}
public void fullInfo() {
CustomerDao dao = new CustomerDao();
List<Customer> lc = dao.getCustomerById(selectedname);
System.out.println(lc.get(0).firstName);
this.custId = lc.get(0).custId;
this.firstName = lc.get(0).firstName;
this.lastName = lc.get(0).lastName;
this.email = lc.get(0).email;
this.dob = lc.get(0).dob;
this.sd = sdf.format(dob);
}
private void clearAll() {
this.firstName = "";
this.lastName = "";
this.sd = "";
this.email = "";
this.custId=0;
}
}
hibernate.cfg.xml
<?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.dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
<property name="hibernate.connection.url">jdbc:derby://localhost:1527/derbyDB</property>
<property name="hibernate.connection.username">user1</property>
<property name="hibernate.connection.password">user1</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.max_size">5</property>
<property name="c3p0.timeout">300</property>
<property name="c3p0.max_statements">50</property>
<property name="c3p0.idle_test_period">300</property>
<mapping class="com.javaknowledge.entity.Customer" resource="com/javaknowledge/entity/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.javaknowledge.entity.Customer" table="CUSTOMERV" schema="APP">
<id name="custId" type="java.lang.Integer">
<column name="cust_id" />
<generator class="increment" />
</id>
<property name="firstName" type="string">
<column name="first_name" length="45" not-null="true" />
</property>
<property name="lastName" type="string">
<column name="last_name" length="45" not-null="true" />
</property>
<property name="email" type="string">
<column name="email" length="45" not-null="true" />
</property>
<property name="dob" type="date">
<column name="dob" length="10" not-null="true" />
</property>
</class>
</hibernate-mapping>

Finally I found a mistake! Hope this is useful to someone. When doing a request to the database(in my case it Apache Derby), name of base need write the first letter upper case other in lower case.
This is wrong query:
session.createQuery("select first_name from CUSTOMERV").
This is valid query
session.createQuery("select first_name from Customerv").
And class entity must be same name as database, but I'm not sure.

in HQL query, Don't write the Table name, write your Entity class name in your query like
String s = "from Entity_class name";
query qry = session.createUqery(s);

In my case I just forgot to add nativeQuery = true
#Query( value = "some sql query ...", nativeQuery = true)
For Spring Boot with Spring Data JPA

If you are using the JPA annotations to create the entities and then make sure that the table name is mapped along with #Table annotation instead of #Entity.
Incorrectly mapped :
#Entity(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
....
....
}
Correctly mapped entity :
#Entity
#Table(name="DB_TABLE_NAME")
public class DbTableName implements Serializable {
....
....
}

hibernate.cfg.xml file should have the mapping for the tables like below. Check if it is missing in your file.
......
<hibernate-configuration>
......
......
<session-factory>
......
<mapping class="com.test.bean.dbBean.testTableHibernate"/>
......
</session-factory>
</hibernate-configuration>
.....

None of the other solution worked for me.
Even if I don't think its the best practice, I Had to add it into the code like this
configuration.addAnnotatedClass(com.myOrg.entities.Person.class);
here
public static SessionFactory getSessionFactory() {
Configuration configuration = new Configuration().configure();
configuration.addAnnotatedClass(com.myOrg.entities.Person.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
return sessionFactory;
}

May be this will make it more clear, and of course makes sense too.
#Entity
#Table(name = "users")
/**
*
* #author Ram Srinvasan
* Use class name in NamedQuery
* Use table name in NamedNativeQuery
*/
#NamedQueries({ #NamedQuery(name = "findUserByName", query = "from User u where u.name= :name") })
#NamedNativeQueries({ #NamedNativeQuery(name = "findUserByNameNativeSQL", query = "select * from users u where u.name= :name", resultClass = User.class) })
public class User implements Principal {
...
}

There is one more chance to get this exception even we used class name i.e., if we have two classes with same name in different packages. we'll get this problem.
I think hibernate may get ambiguity and throws this exception, so the solution is to use complete qualified name(like com.test.Customerv)
I added this answer that will help in scenario as I mentioned. I got the same scenario got stuck for some time.

I too have faced similar issue when i started to work on Hibernate. All in all i can say is in the createQuery one needs to pass the name of the entity class not the table name to which the entity is mapped to.

In Hibernate,
session.createQuery("select first_name from Customerv").
The Customerv is your Entity Name, not your Table Name

It means your table is not mapped to the JPA.
Either Name of the table is wrong (Maybe case sensitive), or you need to put an entry in the XML file.
Happy Coding :)

Other persons that are using mapping classes for Hibernate, make sure that have addressed correctly to model package in sessionFactory bean declaration in the following part:
<property name="packagesToScan" value="com.mblog.model"></property>

In my case: spring boot 2 ,multiple datasource(default and custom). entityManager.createQuery go wrong: 'entity is not mapped'
while debug, i find out that the entityManager's unitName is wrong(should be custom,but the fact is default)
the right way:
#PersistenceContext(unitName = "customer1") // !important,
private EntityManager em;
the customer1 is from the second datasource config class:
#Bean(name = "customer1EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
#Qualifier("customer1DataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.xxx.customer1Datasource.model")
.persistenceUnit("customer1")
// PersistenceUnit injects an EntityManagerFactory, and PersistenceContext
// injects an EntityManager.
// It's generally better to use PersistenceContext unless you really need to
// manage the EntityManager lifecycle manually.
// 【4】
.properties(jpaProperties.getHibernateProperties(new HibernateSettings())).build();
}
Then,the entityManager is right.
But, em.persist(entity) doesn't work,and the transaction doesn't work.
Another important point is:
#Transactional("customer1TransactionManager") // !important
public Trade findNewestByJdpModified() {
//test persist,working right!
Trade t = new Trade();
em.persist(t);
log.info("t.id" + t.getSysTradeId());
//test transactional, working right!
int a = 3/0;
}
customer1TransactionManager is from the second datasource config class:
#Bean(name = "customer1TransactionManager")
public PlatformTransactionManager transactionManager(
#Qualifier("customer1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
The whole second datasource config class is :
package com.lichendt.shops.sync;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "customer1EntityManagerFactory", transactionManagerRef = "customer1TransactionManager",
// 【1】这里写的是DAO层的路径 ,如果你的DAO放在 com.xx.DAO下面,则这里写成 com.xx.DAO
basePackages = { "com.lichendt.customer1Datasource.dao" })
public class Custom1DBConfig {
#Autowired
private JpaProperties jpaProperties;
#Bean(name = "customer1DatasourceProperties")
#Qualifier("customer1DatasourceProperties")
#ConfigurationProperties(prefix = "customer1.datasource")
public DataSourceProperties customer1DataSourceProperties() {
return new DataSourceProperties();
}
#Bean(name = "customer1DataSource")
#Qualifier("customer1DatasourceProperties")
#ConfigurationProperties(prefix = "customer1.datasource") //
// 【2】datasource配置的前缀,对应上面 【mysql的yaml配置】
public DataSource dataSource() {
// return DataSourceBuilder.create().build();
return customer1DataSourceProperties().initializeDataSourceBuilder().build();
}
#Bean(name = "customer1EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
#Qualifier("customer1DataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.lichendt.customer1Datasource.model") // 【3】这里是实体类的包路径
.persistenceUnit("customer1")
// PersistenceUnit injects an EntityManagerFactory, and PersistenceContext
// injects an EntityManager.
// It's generally better to use PersistenceContext unless you really need to
// manage the EntityManager lifecycle manually.
// 【4】
.properties(jpaProperties.getHibernateProperties(new HibernateSettings())).build();
}
#Bean(name = "customer1TransactionManager")
public PlatformTransactionManager transactionManager(
#Qualifier("customer1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}

If you by any chance using java for configuration, you may need to check the below bean declaration if you have package level changes. Eg: com.abc.spring package changed to com.bbc.spring
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
//builder.scanPackages("com.abc.spring"); //Comment this line as this package no longer valid.
builder.scanPackages("com.bbc.spring");
builder.addProperties(getHibernationProperties());
return builder.buildSessionFactory();
}

Should use Entity class name for em.createQuery method
or
Should use em.createNativeQuery method for native query without entity class
With Entity class:
em.createQuery("select first_name from CUSTOMERV")
Without Entity class or Native query:
em.createNativeQuery("select c.first_name from CUSTOMERV c")

Another solution that worked:
The data access object that actually throwed this exception is
public List<Foo> findAll() {
return sessionFactory.getCurrentSession().createQuery("from foo").list();
}
The mistake I did in the above snippet is that I have used the table name foo inside createQuery. Instead, I got to use Foo, the actual class name.
public List<Foo> findAll() {
return sessionFactory.getCurrentSession().createQuery("from Foo").list();
Thanks to this blog: https://www.arundhaj.com/blog/querysyntaxexception-not-mapped.html

Other persons that are using mapping classes for Hibernate, make sure that have addressed correctly to model package in sessionFactory bean declaration in the following part:
public List<Book> list() {
List<Book> list=SessionFactory.getCurrentSession().createQuery("from book").list();
return list;
}
The mistake I did in the above snippet is that I have used the table name foo inside createQuery. Instead, I got to use Foo, the actual class name.
public List<Book> list() {
List<Book> list=SessionFactory.getCurrentSession().createQuery("from Book").list();
return list;
}

add parameter nativeQuery = true
ex:
#Query(value="Update user set user_name =:user_name,password =:password where user_id =:user_id",nativeQuery = true)

In Apache Derby DB, refrain from using table names as "user" or so because they are reserved keywords on Apache Derby but will work fine on MySql.
In the Query, you must specify the name of the Entity class that you want to fetch the data from in the FROM clause of the Query.
List<User> users=session.createQuery("from User").list();
Here, User is the name of my Java Entity class(Consider the casing of the name as in Java it matters.)

in my case was that i forgot the "nativeQuery = true"

Problem partially was solved. Besides creating jdbc/resource(DB Derby) had to create JDBC Connection Pool for db resource in Glassfish admin console, and check it on pinging. Now all CRUD operation work just fine. I check, object Customer in database adding properly, update and delete too. But in Glassfish output log have same exception:
SEVERE: org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped [select concat(first_name, ' ', last_name) as name from CUSTOMERV]
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:96)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234)
.......
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: CUSTOMERV is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)

The mistake in my case is that I used session.createQuery() instead of session.createSQLQuery()

Related

Mybatis 3.4.6 - Data is not being inserted into HSQLDB

I am using Mybatis 3.4.6 in conjunction with HSQLDB 2.4.1 and can't seem to get any data to insert into the database. The program executes without error and seems like it completed, but when I check the database nothing is inserted.
Retrieving/selecting rows from the database seems to work correctly which leads me to believe that something is wrong with my syntax/structure in regards to the 'insert' mapping. Any help would be greatly appreciated.
configuration.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--suppress XmlPathReference -->
<properties resource="org/mybatis/hsqldb/db.properties"/>
<settings>
<!-- Globally enables or disables any caches configured in any mapper under this configuration -->
<setting name="cacheEnabled" value="false"/>
<!-- Sets the number of seconds the driver will wait for a response from the database -->
<setting name="defaultStatementTimeout" value="5"/>
<!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- Allows JDBC support for generated keys. A compatible driver is required.
This setting forces generated keys to be used if set to true,
as some drivers deny compatibility but still work -->
<setting name="useGeneratedKeys" value="true"/>
</settings>
<typeAliases>
<typeAlias type="org.mybatis.hsqldb.POJO.Contact" alias="contact" />
<typeAlias type="org.mybatis.hsqldb.POJO.EIList" alias = "EIList" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!--suppress MybatisConfigXml -->
<property name="driver" value="${jdbc.driver}" />
<!--suppress MybatisConfigXml -->
<property name="url" value="${jdbc.url}" />
<!--suppress MybatisConfigXml -->
<property name="username" value="${jdbc.username}" />
<!--suppress MybatisConfigXml -->
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<!--suppress XmlPathReference -->
<mapper resource="org/mybatis/hsqldb/mappers-xml/ContactMapper.xml" />
<!--suppress XmlPathReference -->
<mapper resource="org/mybatis/hsqldb/mappers-xml/EIListMapper.xml" />
</mappers>
</configuration>
db.properties
jdbc.driver=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:file:hsqldb/db/ipdb;shutdown=true
jdbc.username=admin
jdbc.password=password
Contact.java
package org.mybatis.hsqldb.POJO;
public class Contact {
Integer id;
String lastName;
String firstName;
String phone;
String email;
public Contact(Integer id, String lastName, String firstName, String phone, String email) {
this.id = id;
this.lastName = lastName;
this.firstName = firstName;
this.phone = phone;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
ContactMapper.java
package org.mybatis.hsqldb.mappers_interface;
import java.util.List;
import org.mybatis.hsqldb.POJO.Contact;
public interface ContactMapper {
Integer insert(Contact contact);
List<Contact> selectAll();
Contact select(Integer id);
Integer update(Contact contact);
Integer delete(Integer id);
}
ContactMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="org.mybatis.hsqldb.mappers_interface.ContactMapper">
<insert id="insert" parameterType="contact">
INSERT INTO CONTACT VALUES (${id}, ${lastName}, ${firstName}, ${phone}, ${email})
</insert>
<update id="update">
UPDATE CONTACT SET
"lastName" = #{lastName},
"firstName" = #{firstName},
"phone" = #{phone},
"email" = #{email}
WHERE "id" = #{id}
</update>
<delete id="delete">
DELETE FROM CONTACT WHERE "id" = #{value}
</delete>
<select id="selectAll" resultType="contact">
SELECT "id", "lastName", "firstName", "phone", "email" from CONTACT
</select>
<select id="select" resultType="contact">
SELECT "id", "lastName", "firstName", "phone", "email" from CONTACT where "id" = #{value}
</select>
</mapper>
Driver.java
package org.mybatis.hsqldb;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.hsqldb.POJO.Contact;
import org.mybatis.hsqldb.POJO.EIList;
import org.mybatis.hsqldb.mappers_interface.ContactMapper;
import org.mybatis.hsqldb.mappers_interface.EIListMapper;
public class Driver {
public static void main(String[] args)
{
SqlSessionFactory sqlMapper = null;
String resource = "org/mybatis/hsqldb/configuration.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Problem opening configuration.xml");
}
SqlSession session = sqlMapper.openSession();
try {
ContactMapper mapper = session.getMapper(ContactMapper.class);
Contact testContact = new Contact(3,"'last'","'first'","'phone'","'email'");
int result = mapper.insert(testContact);
session.commit();
} finally {
session.close();
}
}
}
If this is a dumb question/has been asked before I apologize. Been banging my head on my keyboard for the past couple hours and can't figure out the problem.
I'll add this comment as an answer since there's no much room in the comment, but it's a comment.
You say there's no error. I can only think of two things:
The database is somehow temporary and it's not persisted on the filesystem, or is deleted once the connection is shutdown; or
There's a silent error in the execution.
I would suggest enabling MyBatis DEBUG mode. I use Log4j (but any other logging works) and for your case you should add a line like:
log4j.logger.org.mybatis.hsqldb.mappers_interface.ContactMapper=DEBUG
This will show you step by step each execution. Most of the time the DEBUG level is enough for me, but you can enhance it to TRACE to see more.
Anyway, see MyBatis Logging for details.
Solved my own issue so I'll answer it here for anyone else who runs into the same problem.
In the .script file I set the 'File Write Delay' to 0 ms as opposed to the original delay of 500 ms which did not seem to persist any writes to the database.
Normal database operations are successful now.

Why am I getting a org.hibernate.MappingException with this code sample?

.hibernate.MappingException: Repeated column in mapping for entity: com.sample.User2 column: CITY_NAME (should be mapped with insert="false" update="false")
is the Exception I am getting when I run my program that uses Hibernate and MSSQL Server. Here is my code, which is from an online tutorial. I am not sure where the issue lies and I have of course Googled a lot but everything I found had a more obvious error. I can't seem to find it here. Keep in mind, this is my second day using Hibernate/JPA.
com.sample.Address.java:
package com.sample;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class Address {
#Column(name="CITY_STREET")
private String street;
#Column(name="CITY_NAME")
private String city;
#Column(name="STATE")
private String state;
#Column(name="CITY_ZIP")
private String zip;
public Address() { }
public Address(String street, String city, String state, String zip) {
this.street = street;
this.city = city;
this.state = state;
this.zip = zip;
}
//Setters and getters generate by Eclipse (omitted for length)
//Note: No annotations on methods
}
com.sample.User2:
package com.sample;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="FancyTable")
public class User2 {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="USER_ID")
private int userId;
#Column(name="USER_NAME")
private String userName;
#Embedded
#AttributeOverrides({
#AttributeOverride(column = #Column(name="HOME_STREET_NAME"), name = "CITY_STREET"),
#AttributeOverride(column = #Column(name="HOME_CITY_NAME"), name = "CITY_NAME"),
#AttributeOverride(column = #Column(name="HOME_STATE"), name = "STATE"),
#AttributeOverride(column = #Column(name="HOME_CITY_ZIP"), name = "CITY_ZIP")})
private Address homeAddress;
#Embedded
private Address officeAddress;
public User2() { }
//Setters and getters generated by Eclipse (Omitted for length)
//Note: No annotations on methods
}
com.sample.HibernateTest3.java:
package com.sample;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class HibernateTest3 {
static void run() {
User2 user = new User2();
User2 user2 = new User2();
user.setUserName("Test");
user2.setUserName("Test 2");
Address add1 = new Address();
add1.setStreet("street 1");
add1.setCity("city 1");
add1.setState("state 1");
add1.setZip("zip 1");
Address add2 = new Address();
add2.setStreet("street 2");
add2.setCity("city 2");
add2.setState("state 2");
add2.setZip("zip 2");
user.setHomeAddress(add1);
user2.setHomeAddress(add2);
user.setOfficeAddress(new Address("a", "b", "c", "d"));
user.setOfficeAddress(new Address("X", "X", "X", "X"));
SessionFactory sf = null;
try {
sf = HibernateUtils.createSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.save(user);
session.save(user2);
session.getTransaction().commit();
} catch (Exception e) {
System.out.println("ERROR");
e.printStackTrace();
} finally {
try {
HibernateUtils.close();
} catch (Exception ex) {
System.out.println("ERROR 2");
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
run();
}
}
And finally, my hibernate.cfg.xml file...
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://localhost:1433;databaseName=sample1</property>
<property name="connection.username">sa</property>
<property name="connection.password">OMMITED</property>
<!-- MSSQL Dialect -->
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- Names the annotated entity class -->
<mapping class="com.sample.User2"/>
</session-factory>
</hibernate-configuration>
Can someone please shed some light and tell me what precisely is causing this error?
From the docs of #AttributeOverride
(Required) The name of the property whose mapping is being overridden
if property-based access is being used, or the name of the field if
field-based access is used.
so you should use a field name instead of column names e.g.
#AttributeOverride(column = #Column(name="HOME_STREET_NAME"), name = "street")
otherwise the column name is not changed and you get your exception

Hibernate event listeners for JPA callbacks

How can I enable the Hibernate event listeners, that handle JPA callbacks?
Currently I am using using Hibernate 4 with SessionFactory configuration, but JPA callbacks are not running properly, when I persist an object.
Any suggestion are most welcome.
Source code
Temp Entity class:
package com.esp.entity;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.PostLoad;
import javax.persistence.Table;
import com.esp.aaa.TempVal;
#Entity
#EntityListeners(value=TempVal.class)
#Table(name="TEMP")
public class Temp {
private int id;
private String name;
private String email;
private int roll;
#Id #GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getRoll() {
return roll;
}
public void setRoll(int roll) {
this.roll = roll;
}
#PostLoad
public void load(){
System.out.println("post load called here");
}
}
TempVal class:
package com.esp.aaa;
import javax.persistence.PrePersist;
public class TempVal {
#PrePersist
public void validate(Object temp){
System.out.println("Object will persist now");
}
}
MainClass class:
package com.esp.aaa;
import org.hibernate.Session;
import com.esp.entity.Temp;
import com.esp.utility.HibernateUtils;
public class MainClass {
public static void main(String args[]) {
HibernateUtils.createSessionFactory();
Session session=HibernateUtils.getSessionFactory().getCurrentSession();
session.beginTransaction();
Temp temp=new Temp();
temp.setEmail("abc#gmail.com");
temp.setName("Lucky");
temp.setRoll(1112);
session.save(temp);
System.out.println("Object persist successfully");
session.getTransaction().commit();
HibernateUtils.shutdown();
}
}
The Hibernate configuration:
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/demo</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping class="com.esp.entity.Temp"/>
</session-factory>
</hibernate-configuration>
Program output
The program output is the following:
Hibernate: insert into TEMP (email, name, roll) values (?, ?, ?)
Object persist successfully
The expected output would be:
Object will persist now
Hibernate: insert into TEMP (email, name, roll) values (?, ?, ?)
Object persist successfully
This question basically asked the same.
So it turns out, that these JPA entity listener annotations are only working when you are using EntityManager in Hibernate (which is understandable). So if you want to use these annotations, you should ditch SessionFactory, and use the JPA-complaint EntityManager or EntityManagerFactory.
I also recommend this approach, because if you are trying to use JPA annotations, it is logical to go for a pure JPA solution, without tying yourself to a Hibernate-specific solution - i.e. SessionFactory.
Add a file named org.hibernate.integrator.spi.Integrator containing a single line
org.hibernate.jpa.event.spi.JpaIntegrator
in your META-INF/services folder. This will enable JPA lifecycle annotations including #EntityListeners for sessionFactory based configurations.

NullPointerException on Hibernate new Configuration();

This is my first time trying out Hibernate with Eclipse and the following are the things I did:
Created a Java Bean called Student.java which is as follows:
package com.jwt.hibernate;
public class Student {
private long id;
private String name;
private String degree;
private String roll;
private String phone;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDegree() {
return degree;
}
public void setDegree(String degree) {
this.degree = degree;
}
public String getRoll() {
return roll;
}
public void setRoll(String roll) {
this.roll = roll;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Created a mapping file, Student.hbm.xml as follows:
<hibernate-mapping>
<class name="com.jwt.hibernate.Student" table="student">
<id column="ID" name="id" type="long" />
<property column="name" name="name" type="string" />
<property column="degree" name="degree" type="string" />
<property column="roll" name="roll" type="string" />
<property column="phone" name="phone" type="string" />
</class>
</hibernate-mapping>
3. Created the hibernate configuration file, hibernate.cfg.xml as follows:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatetutorial</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create </property>
<mapping resource="com/jwt/hibernate/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
Created the class SimpleTest.java which is as follows:
package com.jwt.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class SimpleTest {
public static void main(String[] args) {
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Student student = new Student();
student.setName("Mukesh");
student.setRoll("101");
student.setPhone("8888");
student.setDegree("B.E");
Transaction tx = session.beginTransaction();
session.save(student);
System.out.println("Object saved successfully.....!!");
tx.commit();
session.close();
factory.close();
}
}
Now, when I try to run SimpleTest, I get the following error:
**INFO: HHH000412: Hibernate Core {4.3.7.Final}
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.hibernate.cfg.Configuration.reset(Configuration.java:326)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:291)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:295)
at com.jwt.hibernate.SimpleTest.main(SimpleTest.java:11)
Caused by: java.lang.NullPointerException
at org.hibernate.internal.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:170)
at org.hibernate.cfg.Environment.<clinit>(Environment.java:221)
... 4 more**
I double checked and made sure that all the configuration and jar files were added to the classpath. So that is not the problem. I would really appreciate some insights as to what may have caused this problem and inturn, how to solve it.
Thanks in advance!
I would recommend updating to later version of SLF4J.
Or
Your Hibernate.cfg.xml is not on classpath. What folder is it in?
Edit :
Caused by: java.lang.NullPointerException
at org.hibernate.internal.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:170)
This is actual exception in your code, If your Hibernate.cfg.xml is loaded then check for SELF4J version, Don't use user library to take your jar files, put all libraries in your lib folder and then configure those in class path.
You may find a Java Configuration of Hibernate to be more friendly. Here is an example of one that I did (Note: there are Spring annotations like #Autowired and #PostConstruct in this class so don't get confused):
public class HibernateConfigBean {
private static final Logger logger = Logger.getLogger(HibernateConfigBean.class);
#Autowired private Environment environment;
private SessionFactory sessionFactory;
private Configuration configuration;
#PostConstruct
private void init(){
configuration = new Configuration();
configuration.setProperty("hibernate.dialect", environment.getProperty("hibernate.dialect"));
configuration.setProperty("hibernate.connection.driver_class", environment.getProperty("hibernate.connection.driver_class"));
configuration.setProperty("hibernate.connection.url", environment.getProperty("hibernate.connection.url"));
configuration.setProperty("hibernate.connection.username", environment.getProperty("db_username"));
configuration.setProperty("hibernate.connection.password", environment.getProperty("db_password"));
//Add additional Annotated Classes here
configuration.addAnnotatedClass(UserEntity.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
}
public SessionFactory getSessionFactory(){
return sessionFactory;
}
//This should be visible outside of the package as it's only used by the GenerateDbSchema class
void generateSchema() throws Exception {
try{
new SchemaExport(configuration).create(false, true);
} catch (RuntimeException re){
throw new Exception(re);
}
}
}
Then I just put my values into a properties file :-)

Hibernate and constraints primary key throws a QueryException

Using oracle DB, we created a table without PK (we are aware that its not a good practice, but we are still hoping that someone can help us) and we need to use a constraint as an alternative. We able to insert data to the DB, unfortunately we can't retrieve because it throws an exception.
Exception in thread "main" org.hibernate.QueryException: could not resolve property: name of: hibernate.Person [FROM hibernate.Person WHERE name = :name AND nickname= :nickname]
hibernate-mapping
<hibernate-mapping>
<class name="com.sample.Person" table="PERSONS" schema="person_schema">
<composite-id name="id" >
<key-property name="name" column="NAME" />
<key-property name="nickname" column="NICKNAME" />
</composite-id>
<property name="address" type="java.lang.String">
<column name="ADDRESS" length="100" />
</property>
</class>
</hibernate-mapping>
PersonDao.java
package hibernate;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class PersonDAO extends BaseHibernateDAO {
public List<Person> getAll(Person person) {
try {
Query query = getSession().createQuery("FROM PERSONS " +
"WHERE name = :name " +
"AND nickname = :nickname");
query.setString("name", person.getName());
query.setString("nickname", person.getNickname());
List<Person> persons =(List)query.list();
return persons;
} catch (RuntimeException re) {
System.out.println("get failed");
throw re;
}finally{
getSession().close();
}
}
public void save(Person person) {
try {
Transaction tx = getSession().beginTransaction();
getSession().save(person);
tx.commit();
} ...
}
}
PersonId.java
package hibernate;
import java.io.Serializable;
public class PersonId implements Serializable {
private String name;
private String nickname;
private String address;
// getters & setters .....
// an easy initializing constructor
public PersonId(String name, String nickname, String address){
this.name = name;
this.nickname = nickname;
this.address = address;
}
#Override
public boolean equals(Object arg0) {
if(arg0 == null) return false;
if(!(arg0 instanceof PersonId)) return false;
PersonId arg1 = (PersonId) arg0;
return (this.name.equalsIgnoreCase(arg1.getName())
&& (this.nickname.equalsIgnoreCase(arg1.getNickname()))
&& (this.address.equalsIgnoreCase(arg1.getAddress()))
);
}
#Override
public int hashCode() {
int hsCode;
hsCode = name.hashCode();
hsCode = hsCode + nickname.hashCode();
hsCode = 19 * hsCode + address.hashCode();
return hsCode;
}
}
Person.java
package hibernate;
public class Person {
private PersonId id;
private String name;
private String nickname;
private String address;
//getters and setters ...
}
TestHibernate.java
package test;
import hibernate.Person;
import hibernate.PersonId;
import hibernate.PersonDAO;
import java.util.Iterator;
public abstract class TestHibernate {
public static void main(String[] args) throws InterruptedException {
/*
Person p = new Person();
p.setPersonId(new PersonId("Foor", "Foo", "Sample Address"));
p.setName("Foor");
p.setNickname("Foo");
p.setAddress("Sample Address");
p.setValue("0");
PersonDao dao = new PersonDao();
//dao.save(p);
*/
Person p = new Person();
p.setName("Foor");
p.setNickname("Foo");
PersonDao dao = new PersonDao();
dao.getAll(p);
}
}
Thanks in advance!
A SELECT is missing at the beginning of the query.
And when calling createQuery() you must use JPQL/HQL. So either modify your query to make it HQL (using entity classes names etc...), or use createSQLQuery() instead.
I can see some problems here ( I may be wrong, correct me if I do) -
Query query = getSession().createQuery("FROM PERSONS " +
"WHERE name = :name " +
"AND nickname = :nickname");
Since, you are using HQL,
PERSON should be Person, the property Class name.
Check this link for an explanation.
Thanks

Categories