I have a program that works smoothly on MySQL database. Now for external requirements, I must switch to SQL Server. Thanks to Hibernate the switch was smooth, except for the error:
java.sql.SQLException: ResultSet may only be accessed in a forward direction.
I am getting this error when performing a custom pagination on the data that I get from the database. Below is a minimal example that tries to get and paginate the users stored in the database (the following example assumes that there are at least 3 rows in the table).
Custom pagination:
import org.hibernate.Query;
import org.hibernate.Session;
public class newMain1 {
public static void main(String[] args) {
getList(1, getSession());
getList(2, getSession());
}
private static void getList(int page, Session s) {
int rowsPerPage = 2;
String hql = "FROM User u ";
try {
Query query = s.createQuery(hql);
int start = (page - 1) * rowsPerPage;
query.setFirstResult(start);
query.setMaxResults(rowsPerPage);
//line that throws exception when int page is 2
query.list();
//line that throws exception when int page is 2
} finally {
if (s.isOpen()) {
s.close();
}
}
}
private Session getSession(){
//gets org.hibernate.Session
}
}
User Java POJO:
public class User {
private Long id;
private String username;
private String password;
private String email;
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
User table for SQL Server:
CREATE TABLE [USER] (
ID bigint NOT NULL,
USERNAME varchar(150) NOT NULL UNIQUE,
PASSWORD varchar(150) NOT NULL,
EMAIL varchar(150) NOT NULL UNIQUE,
PRIMARY KEY (ID)
);
Hibernate mapping of User POJO:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="product.model.User" table="USER">
<id column="ID" name="id" type="long">
<generator class="increment"/>
</id>
<property column="EMAIL" name="email" type="string"/>
<property column="USERNAME" name="username" type="string"/>
<property column="PASSWORD" name="password" type="string"/>
</class>
</hibernate-mapping>
Hibernate cfg xml:
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=myDB;prepareSQL=3;sendStringParametersAsUnicode=false;</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">myPassword</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.globally_quoted_identifiers">true</property>
<mapping resource="product_mapping/user.hbm.xml"/>
</session-factory>
I am using SQL Server 2012, JDK 1.8, Hibernate 4.0.1.Final, jtds driver 1.3.1
Please note that getList(1, getSession()) will not throw the exception, whereas getList(2, getSession()) will.
After hours of investigation i have find out that this problem was due to the hibernate dialect that i was using.
The correct dialect, considering the hibernate version i am required to use, is: org.hibernate.dialect.SQLServer2008Dialect
Source: https://forum.hibernate.org/viewtopic.php?p=2452163
I'm having quite the predicament with my Web Application.
For my school project, we have to migrate from classical JDBC Integration to a JPA Integration. As for myself, I've decided to use Hibernate JPA Framework. I've tried in a main inside a SessionBean, it works there. But whenever I integrate it in a Web Servlet, I noticed it returned empty lists. I've tried displaying the size of the lists with System.out.println().
Anyways, I think the problem might be in my persistence.xml, more specifically the lack of a <jta-data-source>something here</jta-data-source> in it.
Here's my persistence.xml, maybe you could see where I'm having issues :
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="PERSISTENCE" transaction-type="JTA">
<description>Hibernate JPA Configuration Example</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>JavaBeans.Employee</class>
<class>JavaBeans.User</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/JEEPRJ?serverTimezone=Europe/Paris"/>
<property name="javax.persistence.jdbc.user" value="jee"/>
<property name="javax.persistence.jdbc.password" value="jee"/>
<property name="javax.persistence.jdbc.serverTimezone" value="Europe/Paris"/>
<property name="javax.persistence.jdbc.useSSL" value="false"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
Here's my Session Bean for Employee :
package SessionBeans;
import JavaBeans.Employee;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
import javax.persistence.Query;
/**
*
*/
#Stateless
public class EmployeeSB {
#PersistenceContext(name="PERSISTENCE")
EntityManager em;
public List<Employee> getAllEmployees(){
String query = "SELECT e FROM Employee e ";
Query q = em.createQuery(query);
List<Employee> employees = q.getResultList();
if(employees!=null){
System.out.println("it's not null list size : " + q.getResultList().size());
for(Employee emp:employees){
System.out.println("id : " + emp.getId());
}
return employees;
}
System.out.println("it's null");
return employees;
}
And my Employee class :
#Entity
#Table(name = "EMPLOYE")
public class Employee implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Integer id;
#Size(max = 255)
#Column(name = "NOM")
public String nom;
#Size(max = 255)
#Column(name = "PRENOM")
public String prenom;
#Size(max = 255)
#Column(name = "TELDOMICILE")
public String telDomicile;
#Size(max = 255)
#Column(name = "TELPORTABLE")
public String telPortable;
#Size(max = 255)
#Column(name = "TELPRO")
public String telPro;
#Size(max = 255)
#Column(name = "ADRESSE")
public String adresse;
#Size(max = 255)
#Column(name = "CODEPOSTAL")
public String codePostal;
#Size(max = 255)
#Column(name = "VILLE")
public String ville;
// #Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
#Size(max = 255)
#Column(name = "EMAIL")
public String email;
public Employee() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getTelDomicile() {
return telDomicile;
}
public void setTelDomicile(String telDomicile) {
this.telDomicile = telDomicile;
}
public String getTelPortable() {
return telPortable;
}
public void setTelPortable(String telPortable) {
this.telPortable = telPortable;
}
public String getTelPro() {
return telPro;
}
public void setTelPro(String telPro) {
this.telPro = telPro;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public String getCodePostal() {
return codePostal;
}
public void setCodePostal(String codePostal) {
this.codePostal = codePostal;
}
public String getVille() {
return ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Employee(String nom, String prenom, String telDomicile, String telPortable, String telPro, String adresse, String codePostal, String ville, String email) {
this.nom = nom;
this.prenom = prenom;
this.telDomicile = telDomicile;
this.telPortable = telPortable;
this.telPro = telPro;
this.adresse = adresse;
this.codePostal = codePostal;
this.ville = ville;
this.email = email;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Employee)) {
return false;
}
Employee other = (Employee) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "JavaBeans.Employee[ id=" + id + " ]";
}
}
(Don't mind the French haha).
Anyways, if somebody sees why the entity manager is returning empty lists, that would help me a lot and make me understand where I made my stupid mistake.
Thanks a lot guys and have a great day,
Fares.
If you copy/paste the same code of the above session bean inside the servlet, be careful about transaction management. Since session beans manage transactions as their default behavior, as you did you have not to manage them in the beans. However servlets don't have such this behavior, and it's your own responsibility to implement them.
Be notice that it would be an anti-pattern to implement database related jobs inside servlets which belongs to the view layer. The better approach is using session beans for such this functionality and just call them inside the view layer.
I managed to find where the issue is. Buckle up for the ride cause it's gonna be a long one.
In my persistence.xml I never got to define a <jta-data-source></jta-data-source> because I didn't understand it's goal and why we needed to use it.
Since then I have developed a large amount of knowledge and wisdom (not really, basically trial-and-error philosophy).
So. Enough talking. Straight to the answer.
As I said previously the <jta-data-source></jta-data-source> wasn't defined in the persistence.xml in lieu of a huge <properties></properties> section.
Netbeans IDE generates a file in the WEB-INF folder of your directory. It's called glassfish-resources.xml. Our persistence.xml is somewhat binded to it. In the resources file, we define all of our JDBC connection properties. We name it in a pool through a JNDI.
Therefore our new `persistence.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="m1se_appv2_war_1.0PU" transaction-type="JTA">
<jta-data-source>java:app/DBJEE</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
And the (in)famous glassfish-resources.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="mysql_JEEPRJ_jeePool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="serverName" value="localhost"/>
<property name="portNumber" value="3306"/>
<property name="databaseName" value="JEEPRJ"/>
<property name="User" value="jee"/>
<property name="Password" value="***"/>
<property name="URL" value="jdbc:mysql://localhost:3306/JEEPRJ?useSSL=false&serverTimezone=Europe/Paris"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="java:app/DBJEE" object-type="user" pool-name="mysql_JEEPRJ_jeePool"/>
</resources>
BTW If you are using MySQL version above 5.7, absolutely define the useSSL property in URL preferably as false if you don't intend to use it.
The Situation
Ok, so I am learning Hibernate(from 2 days so pardon any blunder), I am using mysql database and just trying tocreate a table Employee and make an entry in database(A demonstration).
Here are the codes
POJO:
package com.sopra.pojo;
import javax.persistence.*;
#Entity
#Table(name = "EMPLOYEE")
public class Employee {
#Id
private int Id;
private String firstName;
private String lastName;
private int salary;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
}
hibernate.cfg.xml which is in src
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://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/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name = "hibernate.hbm2ddl.auto">create</property>
<mapping class="com.sopra.pojo.Employee" />
</session-factory>
</hibernate-configuration>
EmployeeDBManager.java
package com.sopra.pojo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class EmployeeDBManager {
public static void main(String[] args) {
Employee e = new Employee();
e.setFirstName("Salim");
e.setId(672);
e.setLastName("Shamim");
e.setSalary(266);
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.persist(e);
tx.commit();
session.close();
}
}
The Error
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'test.employee' doesn't exist
I've tried
use this in cfg file : <property name="hibernate.hbm2ddl.auto">update</property>
What is interesting is when I manually create the table in mysql using workbench, hibernate does drops it as when i use drop command it says the table doesn't exists.
I can't figure out where the glitch might be(newbie and internet didn't helped).
Please mention any additional details required in comments.
Please help!
Thanks.
I made it worked, I am not sure if it's a proper answer but since it got it working I am posting it as an answer.
I made two changes
I was using hibernate version 5.2.12 so I changed it to 4.2.0 and added jars from two more folders which earlier I hadn't (In summary I have now imported Jars from :optional, provided & required folder in hibernate user library)
I overlooked a url mistake which was
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
In the dtd url I have not added www. It should have been
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">`
So, my mistake.
Anyway, comments regarding improving this answer and why it made it work are deeply appreciated.
add different auto option of hibernate,
Use instead of create , update or create-drop
<property name="hibernate.hbm2ddl.auto">update</property>
or
<property name="hibernate.hbm2ddl.auto">create-drop</property>
You can read more about it here
.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
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()