I am reviewing my Java skills and your support to the community is amazing, your tips have helped me a lot.
I am stuck in a Hibernate #OneToOne configuration, it is a very simple design and code but I can´t find the error. I´d really appreciate your help.
This is the user.java code, the user_id is generated by an autoincrement column at MySQL. I have omitted hash() and equals() code for simplicity. Hibernate understands the User class but something is missing to get to the Address class that is at the other side of the relationship.
Any help would be very appreciated.
Thank you
1) This is the user.java:
package myPackage;
import java.io.Serializable;
import java.util.Arrays;
import javax.persistence.*;
#Entity
#Table(name="user1")
public class User implements Serializable {
private static final long serialVersionUID = 3271213543123246487L;
#Id
#GeneratedValue
#Column(name="user_id")
private Integer user_id;
#Column(name="user_name", length=100, nullable=false)
private String user_name;
#OneToOne (cascade= CascadeType.ALL)
#PrimaryKeyJoinColumn(name="user_id")
private Address myAddress;
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public Address getMyAddress() {
return myAddress;
}
public void setMyAddress(Address myAddress) {
this.myAddress = myAddress;
}
}
2) This is the Address.java code:
package myPackage;
import java.io.Serializable;
import javax.persistence.*;
import org.hibernate.annotations.Parameter;
#Entity
#Table(name="address1")
public class Address implements Serializable {
private static final long serialVersionUID = 3605176021936036836L;
#Id
#GeneratedValue(generator="address_ibfk_2")
#org.hibernate.annotations.GenericGenerator(name="address_ibfk_2",
strategy="foreign",parameters =#Parameter(name="property",value="user1"))
#Column(name="user_id")
private Integer user_id;
#Column(name="address_line1", length=100, nullable=false)
private String address_line1;
public String getAddress_line1() {
return address_line1;
}
public void setAddress_line1(String address_line1) {
this.address_line1 = address_line1;
}
}
3) This is the very simple TestUser class
public class TestUser {
public static void main(String[] args) {
Session mySession = HibernateUtil.getSessionFactory().openSession();
System.out.println("Connection status"+mySession.isConnected());
System.out.println("Session status"+mySession.isOpen());
Transaction myTransaction = mySession.beginTransaction();
try {
User myUser = new User();
Address myAddress = new Address();
myUser.setUser_name("TesteO2O");
myAddress.setAddress_line1("Rua A");
myUser.setMyAddress(myAddress);
mySession.save(myUser);
myTransaction.commit();
System.out.println("myUser saved sucessfully");
} catch (Exception e) {
e.printStackTrace();
myTransaction.rollback();
} finally {
mySession.close();
}
}
}
4) This is the hibernate.cfg.xml config 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>
<!--MySQL Config-->
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/p2pl_dev?serverTimezone=UTC</property>
<property name="connection.username">xyz</property>
<property name="connection.password">blabla</property>
<property name="current_session_context_class">thread</property>
<!--Connection Pool Config: max_statements cached, idle time in seconds-->
<property name="c3po.min_size">2</property>
<property name="c3po.max_size">3</property>
<property name="c3po.timeout">300</property>
<property name="c3po.max_stamentes">50</property>
<property name="c3po.idle_test_period">3000</property>
<!--Debug Config, show_sql=console, format_sql=legible -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="generate_statistics">true</property>
<property name="use_sql_comments">true</property>
<!-- Classes -->
<mapping class="myPackage.User"/>
<mapping class="myPackage.Address"/>
</session-factory>
</hibernate-configuration>
5) Finally the error trace
Hibernate:
/* insert myPackage.User
*/ insert
into
user1
(user_name)
values
(?)
java.lang.NullPointerException
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:650)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:4736)
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:96)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676)
at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:235)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:294)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
at myPackage.TestUser.main(TestUser.java:26)
Related
I'm trying to make an interface for my database created in MySQL Workbench, and i can't simply view the data from any table. I can add a client, and then it appears on Workbench, but not in .jsp file. What am i missing ?
pojo.Clienti
package pojo;
import java.util.HashSet;
import java.util.Set;
public class Clienti implements java.io.Serializable {
private Integer idclient;
private String nume_institutie_firma;
private String cod_unic;
private String adresa;
private Set angajats = new HashSet(0);
public Clienti() {
}
public Clienti(String nume_institutie_firma, String cod_unic, String adresa, Set angajats) {
this.nume_institutie_firma = nume_institutie_firma;
this.cod_unic = cod_unic;
this.adresa = adresa;
this.angajats = angajats;
}
public Integer getIdclient() {
return this.idclient;
}
public void setIdclient(Integer idclient) {
this.idclient = idclient;
}
public String getnume_institutie_firma() {
return this.nume_institutie_firma;
}
public void setnume_institutie_firma(String nume_institutie_firma) {
this.nume_institutie_firma = nume_institutie_firma;
}
public String getcod_unic() {
return this.cod_unic;
}
public void setcod_unic(String cod_unic) {
this.cod_unic = cod_unic;
}
public String getAdresa() {
return this.adresa;
}
public void setAdresa(String adresa) {
this.adresa = adresa;
}
public Set getAngajats() {
return this.angajats;
}
public void setAngajats(Set angajats) {
this.angajats = angajats;
}
}
pojo.Clienti.hbm.xml
<?xml version="1.0"?>
<!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="pojo.Clienti" table="clienti" catalog="tema"
optimistic-lock="version">
<id name="idclient" type="java.lang.Integer">
<column name="idclient" />
<generator class="identity" />
</id>
<property name="nume_institutie_firma" type="string">
<column name="nume_institutie_firma" length="45" />
</property>
<property name="cod_unic" type="string">
<column name="cod_unic" length="45" />
</property>
<property name="adresa" type="string">
<column name="adresa" length="45" />
</property>
<set name="angajats" table="angajati" inverse="true"
lazy="true" fetch="select">
<key>
<column name="idclient" />
</key>
<one-to-many class="pojo.Angajati" />
</set>
</class>
</hibernate-mapping>
*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.hbm2ddl.auto">update</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/tema</property>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">pass</property>
<mapping resource="pojo/Angajati.hbm.xml"/>
<mapping resource="pojo/Clienti.hbm.xml"/>
<mapping resource="pojo/Proiecte.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hibernate.reveng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
<schema-selection match-catalog="tema"/>
<table-filter match-name="proiecte"/>
<table-filter match-name="clienti"/>
<table-filter match-name="angajati"/>
</hibernate-reverse-engineering>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>ClientiController</servlet-name>
<servlet-class>Controller.ClientiController</servlet-class>
</servlet>
<servlet>
<servlet-name>ProiecteController</servlet-name>
<servlet-class>Controller.ProiecteController</servlet-class>
</servlet>
<servlet>
<servlet-name>AngajatiController</servlet-name>
<servlet-class>Controller.AngajatiController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ClientiController</servlet-name>
<url-pattern>/ClientiController</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ProiecteController</servlet-name>
<url-pattern>/ProiecteController</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AngajatiController</servlet-name>
<url-pattern>/AngajatiController</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
DAO.ClientiDao
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package DAO;
import java.util.List;
import pojo.Clienti;
/**
*
* #author vali
*/
public interface ClientiDao {
public void adaugaClienti (Clienti client);
public List<Clienti> afiseazaClienti();
public void modificaClienti (int idclient, String nume_institutie_firma, String cod_unic, String adresa);
public void stergeClient (Clienti client);
}
DAOImpl.ClientiDaoImpl
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package DAOImpl;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import pojo.Clienti;
import DAO.ClientiDao;
/**
*
* #author vali
*/
public class ClientiDaoImpl implements ClientiDao{
public void adaugaClienti(Clienti client) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
session.save(client);
transaction.commit();
session.close();
}
public List<Clienti> afiseazaClienti() {
List<Clienti> listaClienti = new ArrayList();
Session session = HibernateUtil.getSessionFactory().openSession();
org.hibernate.Query query = session.createQuery("From Clienti");
listaClienti = query.list();
return listaClienti;
}
public void modificaClienti(int idclient, String nume_institutie_firma, String cod_unic, String adresa) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
Clienti detaliiclienti = (Clienti) session.load(Clienti.class, idclient);
detaliiclienti.setnume_institutie_firma(nume_institutie_firma);
detaliiclienti.setcod_unic(cod_unic);
detaliiclienti.setAdresa(adresa);
session.update(detaliiclienti);
transaction.commit();
session.close();
}
public void stergeClient(Clienti client) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
session.delete(client);
transaction.commit();
session.close();
}
}
Controller.ClientiController
package Controller;
import DAO.ClientiDao;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import pojo.Clienti;
import DAOImpl.ClientiDaoImpl;
/**
*
* #author vali
*/
public class ClientiController extends HttpServlet {
Clienti client = new Clienti();
ClientiDaoImpl clientDaoImpl = new ClientiDaoImpl();
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (request.getParameter("adaugaClient") != null) {
String nume_institutie_firma = request.getParameter("nume_institutie_firma");
String cod_unic = request.getParameter("cod_unic");
String adresa = request.getParameter("adresa");
client.setnume_institutie_firma(nume_institutie_firma);
client.setcod_unic(cod_unic);
client.setAdresa(adresa);
clientDaoImpl.adaugaClienti(client);
RequestDispatcher rd = request.getRequestDispatcher("adauga_Client.jsp");
rd.forward(request, response);
}
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (request.getParameter("afiseazaClienti") != null) {
List<Clienti> listaClienti = new ArrayList();
listaClienti = clientDaoImpl.afiseazaClienti();
request.setAttribute("listaClienti", listaClienti);
RequestDispatcher rd = request.getRequestDispatcher("tabela_Clienti.jsp");
rd.forward(request, response);
}
if (request.getParameter("modificaClient") != null) {
int id1 = Integer.parseInt(request.getParameter("idclient"));
String nume_institutie_firma = request.getParameter("nume_institutie_firma");
String cod_unic = request.getParameter("cod_unic");
String adresa = request.getParameter("adresa");
clientDaoImpl.modificaClienti(id1, nume_institutie_firma, cod_unic, adresa);
RequestDispatcher rd = request.getRequestDispatcher("adauga_Client.jsp");
rd.forward(request, response);
}
if (request.getParameter("stergeClient") != null) {
int id2 = Integer.parseInt(request.getParameter("idclient"));
client.setIdclient(id2);
clientDaoImpl.stergeClient(client);
RequestDispatcher rd = request.getRequestDispatcher("adauga_Client.jsp");
rd.forward(request, response);
}
}
/**
* Returns a short description of the servlet.
*
* #return a String containing servlet description
*/
#Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Emp.java
package com.management;
public class Emp {
private int id;
private String name;
private float salary;
private String designation;
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 float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
}
EmpController.java
package com.management;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.management.Emp;
import com.management.EmpDao;
#Controller
public class EmpController {
#Autowired
EmpDao dao;//will inject dao from xml file
/*It displays a form to input data, here "command" is a reserved request attribute
*which is used to display object data into form
*/
#RequestMapping("/empform")
public ModelAndView showform(){
return new ModelAndView("empform","command",new Emp());
}
/*It saves object into database. The #ModelAttribute puts request data
* into model object. You need to mention RequestMethod.POST method
* because default request is GET*/
#RequestMapping(value="/save",method = RequestMethod.POST)
public ModelAndView save(#ModelAttribute("emp") Emp emp){
dao.save(emp);
return new ModelAndView("redirect:/viewemp");//will redirect to viewemp request mapping
}
/* It provides list of employees in model object */
#RequestMapping("/viewemp")
public ModelAndView viewemp(){
List<Emp> list=dao.getEmployees();
return new ModelAndView("viewemp","list",list);
}
/* It displays object data into form for the given id.
* The #PathVariable puts URL data into variable.*/
#RequestMapping(value="/editemp/{id}")
public ModelAndView edit(#PathVariable int id){
Emp emp=dao.getEmpById(id);
return new ModelAndView("empeditform","command",emp);
}
/* It updates model object. */
#RequestMapping(value="/editsave",method = RequestMethod.POST)
public ModelAndView editsave(#ModelAttribute("emp") Emp emp){
dao.update(emp);
return new ModelAndView("redirect:/viewemp");
}
/* It deletes record for the given id in URL and redirects to /viewemp */
#RequestMapping(value="/deleteemp/{id}",method = RequestMethod.GET)
public ModelAndView delete(#PathVariable int id){
dao.delete(id);
return new ModelAndView("redirect:/viewemp");
}
}
EmpDao.java
package com.management;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.management.Emp;
public class EmpDao {
JdbcTemplate template;
public void setTemplate(JdbcTemplate template) {
this.template = template;
}
public int save(Emp p){
String sql="insert into Emp99(name,salary,designation) values('"+p.getName()+"',"+p.getSalary()+",'"+p.getDesignation()+"')";
return template.update(sql);
}
public int update(Emp p){
String sql="update Emp99 set name='"+p.getName()+"', salary="+p.getSalary()+", designation='"+p.getDesignation()+"' where id="+p.getId()+"";
return template.update(sql);
}
public int delete(int id){
String sql="delete from Emp99 where id="+id+"";
return template.update(sql);
}
public Emp getEmpById(int id){
String sql="select * from Emp99 where id=?";
return template.queryForObject(sql, new Object[]{id},new BeanPropertyRowMapper<Emp>(Emp.class));
}
public List<Emp> getEmployees(){
return template.query("select * from Emp99",new RowMapper<Emp>(){
public Emp mapRow(ResultSet rs, int row) throws SQLException {
Emp e=new Emp();
e.setId(rs.getInt(1));
e.setName(rs.getString(2));
e.setSalary(rs.getFloat(3));
e.setDesignation(rs.getString(4));
return e;
}
});
}
}
servlet-management.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:context = "http://www.springframework.org/schema/context"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package = "com.spring" />
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/jsp/" />
<property name = "suffix" value = ".jsp" />
</bean>
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://loclahost:3306/test1" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"></property>
</bean>
<bean id="dao" class="com.spring.EmpDao">
<property name="template" ref="jt"></property>
</bean>
</beans>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>management</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>management</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
hi
my trying to insert the value to the database by using the spring-mvc.
and using the mysql database.
while execution process it shows the error like that-org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.spring.EmpDao] for bean with name 'dao' defined in ServletContext resource [/WEB-INF/management-servlet.xml]; nested exception is java.lang.ClassNotFoundException: com.spring.EmpDao .
please provide the soluation.
thank you.
My web project ,spring spring-mvc and hibernate,when the tomcat start there is no tables created in mysql db. why? and no error info
the sessionFactory
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.woodcoder.bean</value>
</list>
</property>
</bean>
the properties
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=false
and I tried hibernate.hbm2ddl.auto=create, it's the same.
Why hibernate doesn't create a table?
The Entity
#Entity
#Table(name="user_bean")
public class UserBean extends BaseBean {
private String username;
private String password;
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;
}
}
the baseEntity
#MappedSuperclass
public class BaseBean implements Serializable{
/**
* ID
*/
#Id
#Column(name="id",length = 32, nullable = true)
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
private String id;
#Column(updatable = false)
private Date createDate;
private Date modifyDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
yes,i got the problem.
in the hibernate config there are some space in the end of each line,although i cant see them.i delete these space,the table was created.
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=false
I have a legacy app that uses:
hibernate-3.5.5.jar
hibernate-jpa-2.0-api-1.0.0.jar
Spring 3.0.2
Tapestry 5.3.8
MySQL
Tomcat 7.0.64
It has a serious issue with multiple users updating the same table row at the same time and loosing the first update. Basically user A says "I want to own the record" (place my id in the record) and user B says "I want to own the record" the code being processed takes a bit of time. So user A gets it and then user B doesn't notice that user A had it and so user B gets it when he shouldn't have because user A already had it.
I've tried using:
#org.hibernate.annotations.Entity(dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL)
on the Entity class for the table and watching the SQL that hibernate produces it never adds the table columns to the SQL update statement. It simply has update ... where id=?.
I've also tried adding a version column to the table in question and the Entity class and annotated the field with
#Version.
This has exactly the same effect as above, nothing in the generated SQL is using the version column. It never gets incremented either.
I'm guessing that I'm missing something with setting this up or there is something about the way the app uses hibernate that is keeping this from working as everything I have read says it should "Just Work".
appContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Configurer that replaces ${...} placeholders with values from a properties
file -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:app_jdbc.properties"/>
</bean>
<!-- Message source for this context, loaded from localized files -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>app_app</value>
<value>app_env</value>
<value>pdf</value>
</list>
</property>
</bean>
<!-- Define data source -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>${jdbc.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<property name="defaultAutoCommit">
<value>${jdbc.autoCommit}</value>
</property>
<property name="maxActive">
<value>${dbcp.maxActive}</value>
</property>
<property name="maxWait">
<value>${dbcp.maxWait}</value>
</property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
...
<value>company.app.domain.Overtime</value>
...
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative
to JTA) -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!-- regular beans -->
<bean id="baseDao" class="vive.db.BaseHbDao">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
...
<bean id="overtimeDao" class="company.app.dataaccess.OvertimeDao">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
...
<!-- service beans -->
<bean id="appService" class="company.app.services.AppService">
<property name="baseDao"><ref local="baseDao"/></property>
...
</bean>
<!-- transaction advice -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="serviceOperation"
expression="execution(* company.app.services.*Service.*(..))" />
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice" />
</aop:config>
</beans>
Overtime Entity class:
package company.app.domain;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.OptimisticLockType;
#Entity
#Table(name = "over_time")
#org.hibernate.annotations.Entity(dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL)
public class Overtime implements java.io.Serializable {
private static final long serialVersionUID = 7263309927526074109L;
#Id
#GeneratedValue(generator = "ot_gen")
#GenericGenerator(name = "ot_gen", strategy = "hilo", parameters = {
#Parameter(name = "table", value = "unique_key"), #Parameter(name = "column", value = "next_hi"),
#Parameter(name = "max_lo", value = "99") })
private Integer id;
#Deprecated
#Column(name = "from_time")
private Date fromTime;
#Deprecated
#Column(name = "to_time")
private Date toTime;
#Column(name = "fm_dttm")
private Long fromDttm;
#Column(name = "to_dttm")
private Long toDttm;
#Column(name = "post_dttm")
private Long postDttm;
private String dow;
private String shift;
#Column(name = "sub_groups")
private String subGroups;
#Column(name = "created_by")
private String createdBy;
#Column(name = "signed_up_by")
private String signedUpBy;
#Column(name = "signed_up_via")
private String signedUpVia;
#Column(name = "date_signed_up")
private Date dateSignedUp;
#Column(name = "signed_up_by_partner_username")
private String signedUpByPartnerUsername;
#Column(name = "signed_up_by_partner_ot_refno")
private String signedUpByPartnerOtRefNo;
private String comment;
private Integer status;
#Column(name = "title_abbrev")
private String titleAbbrev;
#Column(name = "record_status")
private String recordStatus;
#Column(name = "ref_no")
private String refNo;
#Column(name = "ref_id")
private String refId;
#Column(name = "misc_notes")
private String miscNotes;
#Column(name = "sends_notif_upon_posting")
private Boolean sendsNotificationUponPosting;
#Column(name = "notify_post_person_when_filled")
private Boolean notifyPostPersonWhenFilled;
#Column(name = "notify_others_when_filled")
private Boolean notifyOthersWhenFilled;
#Column(name = "vehicle_needed")
private Boolean vehicleNeeded;
#Column(name = "agency_id")
private Integer agencyId;
#Column(name = "schedule_id")
private Integer scheduleId;
#Column(name = "post_date")
private Date postDate;
#Column(name = "enrollment_opens_at")
private Date enrollmentOpensAt;
#Column(name = "enrollment_closes_at")
private Date enrollmentClosesAt;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "class_id")
private OvertimeClass overtimeClass;
public Overtime() {
}
//getters and setters
}
The Tapestry page class where the user tries to sign up for the overtime:
package company.app.pages;
import java.io.*;
import java.text.MessageFormat;
import java.util.*;
import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.PageRenderLinkSource;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestGlobals;
import org.hibernate.StaleObjectStateException;
import org.slf4j.Logger;
import org.springframework.transaction.annotation.Transactional;
import vive.util.*;
import company.t5ext.LabelValueSelectModel;
import company.t5ext.components.DateTimeField;
import company.app.*;
import company.app.domain.*;
import company.app.services.CacheService;
import company.app.services.AppService;
import company.app.comparator.OtComparator;
#RequiresLogin
public class ListPostedOvertime {
#SessionState
#Property
private AppSessionState visit;
#Inject
private RequestGlobals requestGlobals;
#Inject
#Property
private AppService appService;
#Inject
private Request request;
void setupRender() {
...
}
// this method handle the case when a user tries to sign up for an overtime slot
void onSignUp(Integer overtimeId) {
// check to see if the OT has been deleted or modified or signed-up
Overtime ot = (Overtime)appService.getById(Overtime.class, overtimeId);
if (ot == null) {
visit.setOneTimeMessage("The overtime has already been deleted.");
return;
}
if (ot.getStatus() != null && ot.getStatus() != AppConst.OT_NEW) {
visit.setOneTimeMessage("The overtime has already been signed up. Please choose a different one to sign up.");
return;
}
...
try {
appService.validateOvertimeForUser(agency, user, ot);
appService.handleSignUpOvertime(agency, user, ot);
// log activity
String what = "Signed up for overtime " + ot.getRefNo() + ".";
appService.logActivity(user, AppConst.LOG_OVERTIME, what);
} catch(StaleObjectStateException e) {
visit.setOneTimeMessage("The overtime record has been changed by another user, please try again.");
return;
} catch(Exception e) {
visit.setOneTimeMessage(e.getMessage());
return;
}
...
}
}
The AppService class that is used by the Tapestry page to update the overtime record:
package company.app.services;
import java.io.Serializable;
import java.util.*;
import java.text.DecimalFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.springframework.context.support.ResourceBundleMessageSource;
import vive.db.BaseHbDao;
import vive.util.*;
import company.app.*;
import company.app.comparator.LeaveRequestComparator;
import company.app.comparator.UserOtInterestComparator;
import company.app.dataaccess.*;
import company.app.domain.*;
public class AppService
{
private Log log = LogFactory.getLog(this.getClass().getName());
private BaseHbDao baseDao;
private OvertimeDao otDao;
private MiscDao miscDao;
private ResourceBundleMessageSource msgSource;
/**
* Default constructor.
*/
public AppService() {
}
public void save(Object item) {
if (item != null) {
baseDao.save(item);
}
}
public void update(Object item) {
if (item != null) {
baseDao.update(item);
}
}
public void saveOrUpdate(Object item) {
if (item != null) {
baseDao.saveOrUpdate(item);
}
}
public void saveOrUpdateAll(Collection col) {
if (col != null) {
baseDao.saveOrUpdateAll(col);
}
}
public void delete(Object item) {
if (item != null) {
baseDao.delete(item);
}
}
public void deleteAll(Collection col) {
if (col != null) {
baseDao.deleteAll(col);
}
}
public Object getById(Class clazz, Serializable id) {
return baseDao.get(clazz, id);
}
public Object getById(Class clazz, Serializable id, LockMode lockMode) {
return baseDao.get(clazz, id, lockMode);
}
public void validateOvertimeForUser(Agency agency, User user, Overtime ot) throws Exception {
validateOvertimeForUser(agency.getId(), agency, user, ot);
}
public void validateOvertimeForUser(AgencyLite agency, User user, Overtime ot) throws Exception {
validateOvertimeForUser(agency.getId(), agency, user, ot);
}
public void handleSignUpOvertime(AgencyBase agency, User user, Integer otId) {
Overtime ot = (Overtime)getById(Overtime.class, otId);
handleSignUpOvertime(agency, user, ot);
}
public void handleSignUpOvertime(AgencyBase agency, User user, Overtime ot) {
handleSignUpOvertime(agency, user, ot, 1.0d);
}
public void handleSignUpOvertime(AgencyBase agency, User user, Integer otId, Double ptsPerOt) {
Overtime ot = (Overtime)getById(Overtime.class, otId);
handleSignUpOvertime(agency, user, ot, ptsPerOt);
}
public void handleSignUpOvertime(AgencyBase agency, User user, Overtime ot, Double ptsPerOt) {
handleSignUpOvertime(agency, user, ot, ptsPerOt, null, null);
}
public void handleSignUpOvertime(AgencyBase agency, User user, Overtime ot, Double ptsPerOt, String viaUsername, String viaName) {
Date today = new Date();
boolean isOtConfirmRequired = AppUtil.isTrue(agency.getOtConfirmRequired());
Integer otConfirmThreshold = 0;
if (agency.getOtConfirmThreshold() != null) {
otConfirmThreshold = agency.getOtConfirmThreshold();
}
long otInDays = (ot.getFromDttm() - today.getTime()) / AppConst.MILLIS_IN_DAY;
ot.setSignedUpBy(user.getUsername());
ot.setDateSignedUp(today);
ot.setSignedUpVia(viaUsername);
if (isOtConfirmRequired && otInDays >= otConfirmThreshold) {
ot.setStatus(AppConst.OT_PDG);
} else {
ot.setStatus(AppConst.OT_FIN);
}
saveOrUpdate(ot);
user.setLastOtSignupDate(today);
user.setPoints(AppUtil.addPoints(ptsPerOt, user.getPoints()));
saveOrUpdate(user);
...
// email notification sent from caller
}
...
}
The base class for all of the DAO classes:
package vive.db;
import java.io.Serializable;
import java.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.HibernateException;
import org.hibernate.type.Type;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import vive.XException;
import vive.util.XUtil;
/**
* The superclass for hibernate data access object.
*/
public class BaseHbDao extends HibernateDaoSupport implements BaseHbDaoInterface
{
private Log log;
public BaseHbDao() {
super();
log = LogFactory.getLog(getClass());
}
...
/**
* Save or update an object.
*/
public void saveOrUpdate(Object obj) {
getHibernateTemplate().saveOrUpdate(obj);
}
public void save(Object obj) {
getHibernateTemplate().save(obj);
}
public void update(Object obj) {
getHibernateTemplate().update(obj);
}
/**
* Delete an object.
*/
public void delete(Object obj) {
getHibernateTemplate().delete(obj);
}
/**
* Retrieve an object of the given id, null if it does not exist.
* Similar to "load" except that an exception will be thrown for "load" if
* the given record does not exist.
*/
public Object get(Class clz, Serializable id) {
return getHibernateTemplate().get(clz, id);
}
public Object get(Class clz, Serializable id, LockMode lockMode) {
return getHibernateTemplate().get(clz, id, lockMode);
}
...
public void flush() {
getHibernateTemplate().flush();
}
/**
* Retrieve a HB session.
* Make sure to release it after you are done with the session by calling
* releaseHbSession.
*/
public Session getHbSession() {
try {
return getSession();
} catch (Exception e) {
return null;
}
}
/**
* Release a HB Session
*/
public void releaseHbSession(Session sess) {
releaseSession(sess);
}
}
Okay I got it working!
First, I'm using the #Version annotation so I added a version column to the table with the problem.
alter table over_time add version INT(11) DEFAULT 0;
Second, add the Version annotation and member to the Entity class:
public class Overtime implements java.io.Serializable {
private static final long serialVersionUID = 7263309927526074109L;
#Id
#GeneratedValue(generator = "ot_gen")
#GenericGenerator(name = "ot_gen", strategy = "hilo", parameters = {
#Parameter(name = "table", value = "unique_key"), #Parameter(name = "column", value = "next_hi"),
#Parameter(name = "max_lo", value = "99") })
private Integer id;
#Version
#Column(name = "version")
private int version;
...
When I tried this the first couple of times I was using an Integer object not an int primitive for the version member of the class. I THINK this was the issue.
Also make sure that the other hibernate specific annotation is NOT on the entity class:
#org.hibernate.annotations.Entity(dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL)
Third, the exception that gets thrown is not what any of the web sites I've read say it should be, so let's catch the one that really is thrown in the Tapestry page class that handles the user signing up for the overtime record.
void onSignUp(Integer overtimeId) {
// check to see if the OT has been deleted or modified or signed-up
Overtime ot = (Overtime)appService.getById(Overtime.class, overtimeId);
if (ot == null) {
visit.setOneTimeMessage("The overtime has already been deleted.");
return;
}
if (ot.getStatus() != null && ot.getStatus() != AppConst.OT_NEW) {
visit.setOneTimeMessage("The overtime has already been signed up. Please choose a different one to sign up.");
return;
}
...
try {
appService.validateOvertimeForUser(agency, user, ot);
appService.handleSignUpOvertime(agency, user, ot);
// log activity
String what = "Signed up for overtime " + ot.getRefNo() + ".";
appService.logActivity(user, AppConst.LOG_OVERTIME, what);
} catch(HibernateOptimisticLockingFailureException x) {
visit.setOneTimeMessage("The overtime record has been changed by another user, please try again.");
return;
} catch(Exception e) {
visit.setOneTimeMessage(e.getMessage());
return;
}
...
I just started to user hibernate and i allways get this Error:
ERROR: HHH000388: Unsuccessful: create table User (id bigint not null auto_increment, mail varchar(255), passwort varchar(255), primary key (id))
ERROR: Got error -1 from storage engine
This is my mapped class:
package Entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class User
{
private long id;
private String mail;
private String passwort;
#Id
#GeneratedValue
#Column(name="id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Column(name="mail")
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
#Column(name="passwort")
public String getPasswort() {
return passwort;
}
public void setPasswort(String passwort) {
this.passwort = passwort;
}
}
It is because "User" is a reserved keyword. You should change your table name.
The annotation below is the solution for this issue.
#Table(name = "users")
Here is the hibernate config:
<?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.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mysql?zeroDateTimeBehavior=convertToNull</property>
<property name="hibernate.connection.username">root</property>
<property name="connection.pool_size">1</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
I don't know why but I had same issue. Then I just change the name for table with #Table(name="Users") annotation and it started to work.
So try changing this
#Entity
public class User
{
}
to This:
#Entity
#Table(name="Users")
public class User
{
}
Wrong
#Entity /* It will map POJO class with DB Table i,e. Hibernate mapping */
#Table() /* Create Table in DB */
public class User {
}
Right
#Entity /* It will map POJO class with DB Table i,e. Hibernate mapping */
#Table(name="F2CUSER") /* Create Table in DB */
public class User {
}
Here I have use #Table(name="F2CUSER") and it works for me