I use JPA MySQL to execute queries to database , but when I try to persists some entity no row is added to the table
Here is persistense.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="avtoparki" transaction-type="RESOURCE_LOCAL">
<description>
Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>Entities.City</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/world" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="tauren993" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<!-- <property name="hibernate.hbm2ddl.auto" value="create" /> -->
</properties>
</persistence-unit>
</persistence>
here is entity class:
#Entity
public class City {
#Id
//#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
int id;
#Column(name="Name")
String name;
#Column(name="CountryCode")
String CountryCode;
#Column(name="District")
String District;
#Column(name="Population")
int Population;
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 getCountryCode() {
return CountryCode;
}
public void setCountryCode(String countryCode) {
CountryCode = countryCode;
}
public String getDistrict() {
return District;
}
public void setDistrict(String district) {
District = district;
}
public int getPopulation() {
return Population;
}
public void setPopulation(int population) {
Population = population;
}
and here is code:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("avtoparki");
EntityManager em = emf.createEntityManager();
City city = new City();
city.setCountryCode("Georgia");
city.setDistrict("AVOIE");
city.setName("Tbilisi");
city.setId(1);
em.persist(city);
em.close();
System.out.println("SAVED");
when I execute there is no error it just doesn't save it to table (the city table exists and the schema is the same
Seems to me, that you are missing a transaction. Try to save your city-object with following code:
private void save (City city, EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
em.persist( city );
tx.commit();
} catch( RuntimeException ex ) {
if( tx != null && tx.isActive() ) tx.rollback();
throw ex;
} finally {
em.close();
}
}
I would try an explicit flush em.persist(), em.flush(), em.close(). Just to verify.
You should create a Default no-args constructor
public City() { }
Hibernate uses reflection to create objects
Related
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.
I'm trying to understand JPA/Hibernate, I'm able to create new database but I don't understand how insert new row in my
database.
This is the code:
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String adress;
private String phoneNumber;
public void setName(String name) {
this.name = name;
}
public void setAdress(String adress) {
this.adress = adress;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getName() {
return name;
}
public String getAdress() {
return adress;
}
public String getPhoneNumber() {
return phoneNumber;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#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 Person)) {
return false;
}
Person other = (Person) 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 "entinty.Person[ id=" + id + " ]";
}
}
The class that create the database is:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public class Main {
public static void main(String args[]) {
Person p = new Person();
p.setName("xxx");
p.setAdress("yyy");
p.setPhoneNumber("zzz");
EntityManagerFactory emf = javax.persistence.Persistence.createEntityManagerFactory("testPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
em.persist(p);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
}
em.close();
emf.close();
}
}
At this point I have a table with one row (with written "xxx-yyy-zzz"). How can I add new row? Creating new Person doesn't work because it creates new table... I only find solution using Session and SessionFactory but I'm not able to use it, because I can't understand how generate a hibernate.cfg.xml (and in general how to create a session object).
Is There a solution using only EntityManager? Or how can I generate/write a hibernate.cfg.xml file? Is there a way to generate automatically it using netbeans?
EDIT: this is my persistence.xml file. Where do I have to put the ? I put it in the *** zone but it doesn't work...
<?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="testPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>test.Person</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/stackoverflow?zeroDateTimeBehavior=convertToNull"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value="leonida95."/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
*****
</properties>
</persistence-unit>
</persistence>
Inside your Persistence Unit file you'll have something like
<properties>
<property name="hibernate.connection.url" value="..." />
<property name="hibernate.connection.driver_class" value="..."/>
...
</properties>
To create tables when the EntityManagerFactory is constructed, just add
<property name="hibernate.hbm2ddl.auto" value="create" />
Your code works fine.
You can call persist as many times as you want, and it will add rows to the target table.
em.persist(person1);
em.persist(person2);
...
persist does not create a table.
I'm trying to learn Hibernate using MySQL built-in database named world. It has three tables called city, country and countrylanguage. What I'm trying to do is execute SQL statement SELECT * FROM world.city;. When I run my project I'm getting error
org.hibernate.hql.internal.ast.QuerySyntaxException: City is not mapped [from City]
I'm using IntelliJ IDEA and Hibernate 5.2.8.
I created mapping xml file like this:
<?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 package="pl.hibernatePackage">
<class name="City" table="city">
<id name="id" column="ID" type="int">
<generator class="native"/>
</id>
<property name="name" column="Name" type="string"/>
<property name="countryCode" column="CountryCode" type="string"/>
<property name="district" column="District" type="string"/>
<property name="population" column="Population" type="int"/>
</class>
</hibernate-mapping>
City.java is presented below:
public class City
{
private Integer id;
private String name;
private String countryCode;
private String district;
private Integer population;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public Integer getPopulation() {
return population;
}
public void setPopulation(Integer population) {
this.population = population;
}
}
I'm creating session in HibernateUtil.java
public class HibernateUtil
{
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
standardServiceRegistryBuilder.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = standardServiceRegistryBuilder.build();
return configuration.buildSessionFactory(serviceRegistry);
}
catch(Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Configuration file
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"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/world</property>
<property name="hibernate.connection.username">test</property>
<property name="hibernate.connection.password">1234</property>
<property name="connection.pool_size">1</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
<!-- List of XML mapping files -->
<mapping resource="pl/hibernatePackage/City.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Main
public class Main
{
public static void main(String[] args)
{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<City> cities = session.createQuery("from City").list();
for(City c : cities) {
System.out.println(c.getId() + "\t" + c.getName() + "\t" + c.getCountryCode() + "\t" + c.getDistrict() +
"\t" + c.getPopulation());
}
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
}
EDIT Full error list
EDIT 2
javac result
I have done some testing and i made it work by using the fully qualified class name:
session.createQuery("from pl.hibernatePackage.City")
Now this is only a workaround without touching your config..
After digging deeper i found out that since hibernate version 5.x, there is a different strategy for building the sessionFactory.
I made your example work by implementing sessionFactory as follows:
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure()
.build();
Metadata metadata = new MetadataSources( standardRegistry )
.getMetadataBuilder()
.build();
return configuration.buildSessionFactory(serviceRegistry);
This is explained with example here: jboss documentation (point 2.4)
Thanks to Maciej's answer and help of other guys I managed to get my example to work by modifying code and cleaning it up a little. I also found out that mapping DB with xml file is outdated so I modifiied properly CityEntity class. Final code:
Main.java
import org.hibernate.Session;
import java.util.List;
public class Main
{
public static void main(String[] args)
{
Session session = HibernateUtil.getSession();
session.beginTransaction();
List<CityEntity> cities = session.createQuery("from CityEntity").list();
for(CityEntity c : cities)
{
System.out.println(c.getId() + "\t" + c.getName() + "\t" + c.getCountryCode() + "\t" + c.getDistrict() +
"\t" + c.getPopulation());
}
session.getTransaction().commit();
HibernateUtil.close();
}
}
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"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/world</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<property name="connection.pool_size">1</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- List of mapped classes -->
<mapping class="CityEntity"/>
</session-factory>
</hibernate-configuration>
HibernateUtil.java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil
{
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure()
.build();
return configuration.buildSessionFactory(standardRegistry);
}
catch(Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Session getSession()
{
return sessionFactory.openSession();
}
public static void close()
{
sessionFactory.close();
}
}
CityEntity.java
import javax.persistence.*;
#Entity
#Table(name = "city", schema = "world")
public class CityEntity
{
private int id;
private String name;
private String countryCode;
private String district;
private int population;
#Basic
#Column(name = "CountryCode")
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
#Id
#Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "Name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "District")
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
#Basic
#Column(name = "Population")
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
My Java Web App reads data from database but when I try to write something, JPA says ok, but the database does not change. I call "merge" method and the data are not being saved on database, only in memory. I can do a SELECT direct into database and see old data. But the Java Console does not throw any Exception as you can see above.
Java Console:
INFO: [EL Finest]: 2011-10-14 15:02:41.847--UnitOfWork(13027895)--Thread(Thread[http-thread-pool-8080-(6),10,Grizzly])--Merge clone with references user1
Change Password's method that is being called:
public static User changePassword(String username, String oldPassword, String newPassword){
User user = userFacade.find(username);
if(user != null && user.getPassword().equals(oldPassword)){
user.setPassword(newPassword);
userFacade.edit(user); // supposed to save the new password on database, but it's not
// at this point, the user has a new password on memory, but on database the password is still the old one
return user;
}
return null;
}
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="APP1PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.company.User</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/app1"/>
<property name="javax.persistence.jdbc.password" value="12345"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
User.java:
#Entity
#Table(name = "user")
#Cache (
type=CacheType.NONE
)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
private String username;
#Basic(optional = false)
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;
}
}
UserFacade.java
public class UserFacade {
private EntityManagerFactory emf = Persistence.createEntityManagerFactory("APP1PU");
private EntityManager em;
protected EntityManager getEntityManager() {
if( em == null ){
em = emf.createEntityManager();
}
return em;
}
public void create(User entity) {
getEntityManager().persist(entity);
}
public void edit(User entity) {
getEntityManager().merge(entity);
}
public void remove(User entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public User find(Object id) {
return getEntityManager().find(entityClass, id);
}
}
Anyone can figure why this behavior? Or has some suggestion of a test I could do?
Thanks in advance!
Try entityManager.flush() after a write operation. Or start a transaction (entityManager.getTransaction().begin()) before your write operation, and then close it at the end (entityManager.getTransaction().commit())
I have an EJB3 entity bean Player which is annotated as given below:
#Entity
#Table(name = "PLAYER")
public class Player {
public Player() {
super();
}
#Id
#GeneratedValue
private String id;
#Column(nullable = false)
private String firstName;
private String lastName;
public String getId() {
return id;
}
public void setId(String id) {
this.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;
}
}
I am using Apache Derby DB to persist this. I have a persistence.xml file which explains the hibernate properties and I have define hibernate.hbm2ddl.auto=create.
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="PlayerApp" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.cricinfo.domain.Player</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.connection.url"
value="jdbc:derby://localhost:1527/PlayerAppDB;create=true" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
But when I try to persist this object I get an exception saying
Caused by: org.apache.derby.client.am.SqlException: Table/View 'PLAYER' does not exist.
at org.apache.derby.client.am.Statement.completeSqlca(Unknown Source)
Isn't it supposed to auto create the tables since I have set the property hibernate.hbm2ddl.auto ? Or is there something that I am missing?
My main method is as shown below:
public static void main(String[] args) {
Player p = new Player();
p.setFirstName("A");
p.setLastName("BC");
EntityManagerFactory factory = Persistence.createEntityManagerFactory("PlayerApp");
EntityManager entityMgr = factory.createEntityManager();
EntityTransaction tx = entityMgr.getTransaction();
tx.begin();
entityMgr.persist(p);
tx.commit();
entityMgr.close();
factory.close();
}
Add the below property
<property name="hibernate.generateDdl" value="true" />