Hibernate session.get() shows null - java

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

Related

Hibernate doesn't save entity

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;
}

Hibernate H2 database not found

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.

Hibernate keeps updating database even when I work with local variables

I encountered an issue, where the items from my database get deleted at a certain point. It seems like Hibernate updates the database when I'm working with local variables.
Here is my hibernate.cfg.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
" http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- MySQL Configuration -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">dbname</property>
<property name="connection.username">dbusername</property>
<property name="connection.password">dbpassword</property>
<property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.show_sql">true</property>
<mapping class="model.User"/>
<mapping class="model.Admin"/>
<mapping class="model.Student"/>
<mapping class="model.Teacher"/>
<mapping class="model.Classroom"/>
<mapping class="model.Quiz"/>
<mapping class="model.Task"/>
<mapping class="model.Solution"/>
<mapping class="model.CorrectSolution"/>
<mapping class="model.WrongSolution"/>
<mapping class="model.Result"/>
</session-factory>
</hibernate-configuration>
I'll post a few examples of code where items get deleted.
This is my own ComboBox class, I save objects of Quiz class in it and I want to remove every Quiz which has an empty TaskList.
private void removeEmptyQuizzes(List<Quiz> quizList){
for(Quiz q : quizList){
if(q.getTaskList().isEmpty()){
quizList.remove(q);
}
}
setItems(FXCollections.observableArrayList(quizList));
}
What happens is that all Quizzes with empty TaskList get completely deleted from the database, not just from the ComboBox.
My application is a Quiz test game, so here's another example. I load the tasks into a List<Task> and then I remove the
private void fillTaskList(){
taskList = SelectedQuiz.getQuiz().getTaskList();
taskNumber = taskList.size();
}
private void loadTask(){
if(!taskList.isEmpty()) {
int taskIndex = new Random().nextInt(taskList.size());
task = taskList.get(taskIndex);
// extra stuff for my quiz - not relevant to the question
/*view.getLbQuestion().setText(task.getQuestion());
List<AnswerBox> answerBoxList = createAnswerBoxList();
List<Solution> solutionList = createSolutionList(task);
int bound = answerBoxList.size();
for(AnswerBox box : answerBoxList){
int index = (new Random().nextInt(bound) + 1) - 1;
Solution sol = solutionList.get(index);
box.setSolution(sol);
solutionList.remove(sol);
bound--;
}*/
taskList.remove(taskList.get(taskIndex));
}
else {
Student student = (Student) LoggedInUtil.getLoggedInUser();
Quiz quiz = SelectedQuiz.getQuiz();
Result result = new Result(correctAnswers, wrongAnswers, student, quiz.getName());
new ResultDao().insertResult(result);
rootView.setEndMiddle(taskNumber, correctAnswers, wrongAnswers);
}
}
Now, I have Tasks saved in the database. However, they all get deleted when I call this new ResultDao().insertResult(result); function. I tried sysouting Quiz.getTaskList.size() in the final else (before saving the Result) and it indeed was 0 and Hibernate updated it.
Now, why does Hibernate automatically update my variables? I have specific Dao classes to work with database, but I don't call them in these cases.
I appreciate all answers, thank you.
EDIT: added InsertResult() method on request
public void insertResult(Result r) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
session.saveOrUpdate(r);
transaction.commit();
}
EDIT2: added mapping for Result class
#Entity
public class Result {
private int result_id, correctAnswers, wrongAnswers;
private Student student;
private SimpleStringProperty quizName = new SimpleStringProperty();
public Result() {
}
public Result(int correctAnswers, int wrongAnswers, Student student, String quizName) {
this.correctAnswers = correctAnswers;
this.wrongAnswers = wrongAnswers;
this.student = student;
this.quizName.set(quizName);
}
#Column(nullable = false)
public int getCorrectAnswers() {
return correctAnswers;
}
public void setCorrectAnswers(int correctAnswers) {
this.correctAnswers = correctAnswers;
}
#Column(nullable = false)
public int getWrongAnswers() {
return wrongAnswers;
}
public void setWrongAnswers(int wrongAnswers) {
this.wrongAnswers = wrongAnswers;
}
#Id
#GenericGenerator(name="id" , strategy="increment")
#GeneratedValue(generator="id")
public int getResult_id() {
return result_id;
}
public void setResult_id(int result_id) {
this.result_id = result_id;
}
#ManyToOne(targetEntity = Student.class)
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
#Column(nullable = false)
public String getQuizName() {
return quizName.get();
}
public SimpleStringProperty quizNameProperty() {
return quizName;
}
public void setQuizName(String quizName) {
this.quizName.set(quizName);
}
#Transient
public SimpleStringProperty studentWithClassProperty(){
String studentWithClass = getStudent().getName() + getStudent().getSurname() + " - " + getStudent().getClassroom().toString();
return new SimpleStringProperty(studentWithClass);
}
}

Hibernate creating wrong create table statement?

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`")

#AttributeOverrides and #Embeddable not working

This is from Hibernate Recipies book at chapter 3 first question when I am trying to run I am getting the following error Exception in thread "main" org.hibernate.MappingException: Repeated column in mapping for entity: com.fun.hibernate.auto.idgen.Order column: address (should be mapped with insert="false" update="false")
Here is the code
#Entity
#org.hibernate.annotations.Entity(dynamicInsert=true, dynamicUpdate=true)
#Table(name="ORDERS")
public class Order {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE,generator="orderSequence" )
#SequenceGenerator(name="orderSequence",sequenceName="ORDERSEQ")
private Long id;
private Contact weekdayContact;
private Contact holidayContact;
public Order() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Contact getWeekdayContact() {
return weekdayContact;
}
public void setWeekdayContact(Contact weekdayContact) {
this.weekdayContact = weekdayContact;
}
#Embedded
#AttributeOverrides({
#AttributeOverride(name="recipient",column=#Column(name ="HOLIDAY_RECIPIENT")),
#AttributeOverride(name="phone",column=#Column(name ="HOLIDAY_PHONE")),
#AttributeOverride(name="address",column=#Column(name ="HOLIDAY_ADDRESS"))
})
public Contact getHolidayContact() {
return holidayContact;
}
public void setHolidayContact(Contact holidayContact) {
this.holidayContact = holidayContact;
}
}
Embeddable Object
#Embeddable
public class Contact {
private String recipient;
private String phone;
private String address;
public Contact() {
}
#Column(name = "WEEKDAY_RECIPIENT")
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
#Column(name ="WEEKDAY_PHONE")
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Column(name ="WEEKDAY_ADDRESS")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Any ideas how to solve this??????????????
Reading the Hibernate Recipes book cited above I could easily reach the exactly point you described on your question.
I couldn't create the same environment that you are working on, so I had to read and interpret what the book says about mapping by annotations and by external configuration files (XML).
By studying your code and the book chapter I think that there are a high probably that you doing some redundancy in the mapping your embedded object, so there is what I think it's the exactly(or close to it) problem:
In the configuration file the book says to create the manual mapping by tags, just like this:
<component name="weekdayContact" class="Contact">
<property name="recipient" type="string" column="WEEKDAY_RECIPIENT" />
<property name="phone" type="string" column="WEEKDAY_PHONE" />
<property name="address" type="string" column="WEEKDAY_ADDRESS" />
</component>
<component name="holidayContact" class="Contact">
<property name="recipient" type="string" column="HOLIDAY_RECIPIENT" />
<property name="phone" type="string" column="HOLIDAY_PHONE" />
<property name="address" type="string" column="HOLIDAY_ADDRESS" />
</component>
Just above this the book also says that you need to create the mapping by annotations:
#Embedded
#AttributeOverrides({
#AttributeOverride(name="recipient",column=#Column(name ="HOLIDAY_RECIPIENT")),
#AttributeOverride(name="phone",column=#Column(name ="HOLIDAY_PHONE")),
#AttributeOverride(name="address",column=#Column(name ="HOLIDAY_ADDRESS"))
})
public Contact getHolidayContact() {
return holidayContact;
}
So, I think that's there only two possible things happening here:
You are mapping the embedded object in the XML file and in the class. In this case you should do it just by one type, preferably by annotations.
I could see that your code differs that the one the book states, and this may be causing the failure. In this case you should read again your whole code and see if there's any differential than the book one, and then correct it to be working just like it's written in the examples.
That's it, good luck!

Categories

Resources