I'm quite new to hibernate so my problem can be obvious to you. I created database in H2 Console with 3 tables (data.mv.db), insert some values and then copied it to my database folder in project path. Now I'm trying to read one of them for tests, but always have error that table not exists. I've tried to add properties to connection url like connection delay or not changing letter to upper case but still the same.
Error:
Caused by: org.h2.jdbc.JdbcSQLException: Tabela "LOGIN_DATA" nie
istnieje Table "LOGIN_DATA" not found; SQL statement: select
login_data0_.ID as ID1_0_, login_data0_.USERNAME as USERNAME2_0_,
login_data0_.PASSWORD as PASSWORD3_0_, login_data0_.FAVOURITE as
FAVOURIT4_0_ from PUBLIC.LOGIN_DATA login_data0_ [42102-192] at
org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179) at
org.h2.message.DbException.get(DbException.java:155) at
org.h2.schema.Schema.getTableOrView(Schema.java:437) at
org.h2.command.Parser.readTableOrView(Parser.java:5371) at
org.h2.command.Parser.readTableFilter(Parser.java:1257) at
org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1896) at
org.h2.command.Parser.parseSelectSimple(Parser.java:2044) at
org.h2.command.Parser.parseSelectSub(Parser.java:1890) at
org.h2.command.Parser.parseSelectUnion(Parser.java:1709) at
org.h2.command.Parser.parseSelect(Parser.java:1697) at
org.h2.command.Parser.parsePrepared(Parser.java:445) at
org.h2.command.Parser.parse(Parser.java:317) at
org.h2.command.Parser.parse(Parser.java:289) at
org.h2.command.Parser.prepareCommand(Parser.java:254) at
org.h2.engine.Session.prepareLocal(Session.java:560) at
org.h2.engine.Session.prepareCommand(Session.java:501) at
org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1201)
at
org.h2.jdbc.JdbcPreparedStatement.(JdbcPreparedStatement.java:73)
at
org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:289)
at
org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:145)
at
org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:171)
... 17 more
Hibernate Config:
<?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">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:~/database/data</property>
<property name="connection.username">admin</property>
<property name="connection.password">1234</property>
<property name="hibernate.default_schema">PUBLIC</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</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>
<mapping class="data.Login_data"/>
</session-factory>
</hibernate-configuration>
Login_data class:
#Entity
#Table(name = "LOGIN_DATA")
public class Login_data {
private int id;
private String name;
private String password;
private String values;
public Login_data() {
// this form used by Hibernate
}
public Login_data(int id, String name, String password, String values) {
this.id = id;
this.name = name;
this.password = password;
this.values = values;
}
#Id
#GeneratedValue
#Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "USERNAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "PASSWORD")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "FAVOURITE")
public String getValues() {
return values;
}
public void setValues(String values) {
this.values = values;
}
}
Main class:
public static void main(String[] args){
Login_data user = new Login_data();
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
/*session.beginTransaction();
session.save(user);
session.getTransaction().commit();*/
// now lets pull events from the database and list them
session.beginTransaction();
List result = session.createQuery("from Login_data").list();
for (Login_data event : (List<Login_data>) result) {
System.out.println(event.getName());
}
System.out.print(result);
session.getTransaction().commit();
session.close();
}
I've tried to edit configuration. So I add:
<property name="hibernate.hbm2ddl.auto">update</property>
And make empty database. What is strange is database and table created by Java after opening in H2 Console is not visible. So that can be the problem.
I wanted to put a lot of data, so how to make it not from java to be visible there?
Thanks to #JB Nizet I see my error. I was copying database to project path, where my path "~/database" shows to database in user folder, and I was copying it to project folder so I should use "./database" .
Still if I want to make runnable I would need to use user location to have it rightly working on other machines.
Related
I'm really new to hibernate and try to understand how it works. But know I faced with the problem.
First of all, I have such mapping:
#Entity
public class Author {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
public Author() {
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
But then, when I tried to save this entitye with session.save(), hibernate showed me error like
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "id" of relation "author" violates not-null constraint
Failing row contains (null, hello!).
So I decided to notice, why hibernate doesn't increment the id automaticy and recognized that POSTGRESQL doesn't suppert annotation GenerationType.IDENTITY. So I changet it to the GenerationType.SEQUENCE. The error was gone, but entity wasn't saved.
So here's hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:postgresql://localhost:5432/hibernate?useSSL=false
&serverTimezone=UTC</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="dialect">org.hibernate.dialect.PostgreSQL9Dialect</property>
<property name="connection.username">postgres</property>
<property name="connection.password">4122</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="hibernate.entity.Author"/>
<!-- DB schema will be updated if needed -->
<!-- <property name="hibernate.hbm2ddl.auto">update</property> -->
</session-factory>
</hibernate-configuration>
Here's HibernateUtil.java
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static SessionFactory buildSessionFactory() {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder()
.build();
SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();
return sessionFactoryBuilder.build();
}
public static SessionFactory getSessionFactory() {
if(sessionFactory == null) {
sessionFactory = buildSessionFactory();
}
return sessionFactory;
}
}
And here's the Main.java, where I call the hibernate functions:
public class Main {
public static void main(String[] args) {
try(Session session = HibernateUtil.getSessionFactory().openSession()) {
Transaction tx = session.beginTransaction();
Author author = new Author();
author.setName("hello!");
session.save(author);
tx.commit();
System.out.println(session.get(Author.class, 1L));
}
}
}
After program execution it prints me null and there is no entity in database:
If you know, what can be the problem, please tell me. I'd really apreciate it!
I think the reason is setter for id missing:
public long setId(long id) {
this.id = id;
}
I am a newbie to hibernate framework. I following a tutorial series available on the this link. Here is my model class
package kasun.hibernate.moreAnnotations;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="UserDetailsMoreAnn")
public class UserDetailsMoreAnnotations {
private int id;
private String name;
private String address;
private Date date;
private String desc;
#Id
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 getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
// public String getDesc() {
// return desc;
// }
// public void setDesc(String desc) {
// this.desc = desc;
// }
}
and this is my Service method
package kasun.hibernate.moreAnnotations;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class ServiceMethod {
public static void main(String[] args) {
UserDetailsMoreAnnotations objct= new UserDetailsMoreAnnotations();
objct.setName("Kalanka");
objct.setId(7);
objct.setAddress("Kuliyapitiya");
objct.setDate(new Date()); // provide the current date
// objct.setDesc("Younger Brother");
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session= sessionFactory.openSession();
session.beginTransaction();
session.save(objct);
session.getTransaction().commit();
}
}
and this is my hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!-- ~ Hibernate, Relational Persistence for Idiomatic Java ~ ~ License:
GNU Lesser General Public License (LGPL), version 2.1 or later. ~ See the
lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. -->
<!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">org.hsq/ldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hsql://localhost/TestDB</property> -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/HibernateTesting1</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- 5) for the kasun.hibernate.moreAnnotations package -->
<mapping class="kasun.hibernate.moreAnnotations.UserDetailsMoreAnnotations" />
</session-factory>
</hibernate-configuration>
Above code runs without errors. The problem I encounter is that when I uncomment the lines
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
in my model class and set a value to desc by uncommenting the line
objct.setDesc("Younger Brother"); in the Service Method
I got a error as Unable to execute command [alter table UserDetailsMoreAnn add column desc varchar(255)] and it says that You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'desc varchar(255)' at line 1. What I am doing wrong? Can anyone help me to fix this.Thanks in advance
DESC is a reserved keyword in MySQL and cannot be used for field name. Try renaming to Description or something. :)
You can also annotate the field, but must use brackets or escaped quotes:
#Column(name = "[DESC]")
public String getDesc() {
or
#Column(name = "\"DESC\"")
public String getDesc() {
list of reserved words for MySQL 5.7: https://dev.mysql.com/doc/refman/5.7/en/keywords.html
desc is keyword in sql. You should use back tick character(`).
Here i cannot use back tick since stack overflow take it as code sample.
So here i use single quotes. 'desc' varchar(255) instead of desc varchar(255) in database. Using back tick symbol, we can use all reserved keyword in mysql
For back tick, refer https://superuser.com/questions/254076/how-do-i-type-the-tick-and-backtick-characters-on-windows
For entity mapping, refer http://www.mkyong.com/hibernate/how-to-use-database-reserved-keyword-in-hibernate/
I am new to Hibernate (implementing since yesterday) and i succesfully created a method, that transfers my Customer Objects to the Database.
After i quit my application and start it again and create a new session (in an other method) based on my hibernate.cfg.xml file with this setting:
<property name="hibernate.hbm2ddl.auto">create</property>
It leads to that point, that all relevant tables, created with Hibernate are being deleted.
So maybe that is a comprehension question, but i think "transparent persistence by hibernate" means also, that my POJO's are persistent beyond the runtime of my application!?
So i read several topics on Stackoverflow and tried it with this setting:
<property name="hibernate.hbm2ddl.auto">update</property>
But this leads to SQL errors:
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
Of course i don't want have duplicates, so i suppose that hibernate doesn't send a SQL Statement referring to an existing object.
It sends a Statement like this:
UPDATE `customer` SET `id`=1,`birthday`='1990-10-05 00:00:00',`forename`='TestCustomer',`gender`='F',`generatedProfitsLastYear`='0',`generatedProfitsTotal`='0',`surename`='A',`gcid`='1'
But i need the same statement, with a
Where `id`=1
at the end.
So basically what i want is, that hibernate doesn't drop all the tables and creates it again when i restart my application and create a new session based on the configuration file. So after i open a new session, i can transfer the Customer Objects stored in the database to POJOs.
Did i understand the concept of hibernate incorrectly or am i making a typical beginners mistake?
Below you will find my Customer Class:
#Entity
#Table(name="CUSTOMER")
public class Customer {
private int id;
private String forename;
private String surname;
private char gender;
private Date birthday;
private double generatedProfitsTotal;
private double generatedProfitsLastYear;
private CustomerGroup assignedTo;
public Customer(int id, String forename, String surname, char gender,
Date birthday) {
super();
this.id = id;
this.forename = forename;
this.surname = surname;
this.gender = gender;
this.birthday = birthday;
}
#Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "forename")
public String getForename() {
return forename;
}
public void setForename(String forename) {
this.forename = forename;
}
#Column(name = "surename")
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
#Column(name = "gender")
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
#Column(name = "birthday")
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
#Column(name = "generatedProfitsTotal")
public double getGeneratedProfitsTotal() {
return generatedProfitsTotal;
}
public void setGeneratedProfitsTotal(double generatedProfitsTotal) {
this.generatedProfitsTotal = generatedProfitsTotal;
}
#Column(name = "generatedProfitsLastYear")
public double getGeneratedProfitsLastYear() {
return generatedProfitsLastYear;
}
public void setGeneratedProfitsLastYear(double generatedProfitsLastYear) {
this.generatedProfitsLastYear = generatedProfitsLastYear;
}
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="gcid", nullable=true, insertable=true, updatable=true)
public CustomerGroup getAssignedTo() {
return assignedTo;
}
public void setAssignedTo(CustomerGroup assignedTo) {
this.assignedTo = assignedTo;
}
}
my hibernate config file:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/hibernatetesting</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="studyproject.Customer"/>
<mapping class="studyproject.CustomerGroup"/>
<mapping class="studyproject.BonusPackage"/>
</session-factory>
</hibernate-configuration>
Thanks
try session.saveOrUpdate() method where you have used session.save() it will prevent your database from dropping while fetching data use it with hbm2ddl.auto update. it worked for me. hope it helps.
What did you do where the 'duplicate error' occurs? Now I have the hibernate.hbm2ddl.auto configured as yours, but it's okay saving or updating entity in my local.
Although I read session.get null problems on stackoverflow and tried to do what they suggested, my problem seems to continue.
SessionFactory mysessionfactory = new Configuration().configure().buildSessionFactory();
Session mysession = mysessionfactory.openSession();
mysession.beginTransaction();
Myperson person3 = (Myperson) mysession.get(Myperson.class, 3);
System.out.println("there you go : "+person3.getName());
As simple as it seems, i am just trying to retrieve data from database. Let me show you the database.
As you can see above , the data i like to retrieve has a name !
This is what i get, NOTHING !
And finally , i run the code with debug mode and i hope you'll understand the problem and suggest a solution.
i am in a conflict here, my database shows that data which has UserId of 3 has a name but why can't i see it in my output ?
EDIT : Here is my hibernate xml file as you requested.
<?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.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.pool.size">1</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/myhibernatedb
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
000003
</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- List of XML mapping files -->
<mapping class="org.emreverim.com.Myperson"/>
<mapping class="org.emreverim.com.Vehicle" />
<mapping class="org.emreverim.com.FourWheeler" />
<mapping class="org.emreverim.com.TwoWheeler" />
</session-factory>
</hibernate-configuration>
EDIT 2 : here is myperson class as you requested.
#Entity
public class Myperson {
#Id #GeneratedValue(strategy=GenerationType.AUTO)
private int userID;
private String name;
#OneToMany(cascade=CascadeType.PERSIST)
private Collection<Vehicle> vehicle = new ArrayList<Vehicle>();
public Collection<Vehicle> getVehicle() {
return vehicle;
}
public void setVehicle(Collection<Vehicle> vehicle) {
this.vehicle = vehicle;
}
#Lob
private String description;
#Temporal (TemporalType.DATE)
private Date joinedDate;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getJoinedDate() {
return joinedDate;
}
public void setJoinedDate(Date joinedDate) {
this.joinedDate = joinedDate;
}
public int getUserID() {
return userID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setUserID(int userID){
this.userID = userID;
}
}
I think the problem here is caused by the fact that Hibernate Session.get() method expects a Seriliazable id object, which is not provided in your case here mysession.get(Myperson.class, 3) .
Because the given value 3 here is of primitive type int which contains only the value and isn't serialized so you have to use new Integer() method in order to pass an Integer serializable object or new Long() to pass a Long serializable object to the get() method, so just change:
Myperson person3 = (Myperson) mysession.get(Myperson.class, 3);
To:
Myperson person3 = (Myperson) mysession.get(Myperson.class, new Integer(3));
Or:
Myperson person3 = (Myperson) mysession.get(Myperson.class, new Long(3));
We happened to see the solution, my database has been configured as utf-16 while it should have been utf-8. so its just as simple as that. i gave thumps up for all answers, thanks for all of your concerns.
In your entity map you forgot to add the annotations #column attributes to the field and #table to link it to the table.
Example:
#Column(name="description")
private String description;
Check this example for the annotations http://archive.oreilly.com/pub/a/onjava/2007/02/08/an-introduction-to-hibernate-3-annotations.html?page=2
It's my first time configuring hibernate. I've read many tutorials but not sure why this is creating the wrong create table sql statement. I am using PostgreSQL as my database.
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.PostgreSQL9Dialect</property>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://DBIP:5432/MYDB</property>
<property name="hibernate.connection.username">MYDB</property>
<property name="hibernate.connection.password">MYPASS</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<mapping class="MYPROJ.model.User"/>
</session-factory>
</hibernate-configuration>
User.java
package MYPROJ.model;
import javax.persistence.*;
#Entity
public class User
{
#Id #GeneratedValue
#Column(name = "id")
private int id;
#Column(name = "username")
private String username;
#Column(name = "age")
private int age;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
Main.java
public class Main
{
public static void main(String[] args)
{
User user = new User();
user.setId(1);
user.setAge(20);
user.setUsername("david");
SessionFactory sessionFactory;
ServiceRegistry serviceRegistry;
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
System.out.println("Done!");
}
}
When I run the program it shows the following SQL statement for creating the table which does not work when I run the program or when I copy pasted it manually
create table User (id int4 not null, age int4, username varchar(255), primary key (id))
What am I doing wrong here?
It turned out that "user" was a reserved keyword in PostgreSQL, changing that fixed the issue.
You can tell hibernate your column name must be escaped to avoid conflicts with the database keywords. To do that, enclose the name between `. Example:
#Column(name="`user`")