Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate DAO setting object value as object

I am trying to use Hibernate on my project << all sources if wanted, I try to create and save an object player on startup, I get the following error:

START SCRIPT!
org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.util.Date centaurus.domain.User.created] by reflection for persistent property [centaurus.domain.User#created] : User{id=0, email='test', created=Wed Jun 08 13:06:53 BST 2016}
    at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43)
    at org.hibernate.property.access.spi.GetterFieldImpl.getForInsert(GetterFieldImpl.java:58)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValuesToInsert(AbstractEntityTuplizer.java:521)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValuesToInsert(PojoEntityTuplizer.java:228)
    at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValuesToInsert(AbstractEntityPersister.java:4701)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:254)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:682)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
    at centaurus.service.player.PlayerDAOimpl.saveUser(PlayerDAOimpl.java:32)
    at centaurus.Dbmaintain.start(Dbmaintain.java:25)
    at restx.factory.Factory.start(Factory.java:846)
    at restx.RestxMainRouterFactory.build(RestxMainRouterFactory.java:450)
    at restx.RestxMainRouterFactory.newInstance(RestxMainRouterFactory.java:70)
    at restx.servlet.RestxMainRouterServlet.init(RestxMainRouterServlet.java:74)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:519)
    at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:331)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:747)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:706)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:492)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
    at org.eclipse.jetty.server.Server.doStart(Server.java:277)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
    at restx.server.JettyWebServer.start(JettyWebServer.java:109)
    at restx.server.JettyWebServer.startAndAwait(JettyWebServer.java:114)
    at centaurus.AppServer.main(AppServer.java:30)
Caused by: java.lang.IllegalArgumentException: Can not set java.util.Date field centaurus.domain.User.created to centaurus.domain.User
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
    at java.lang.reflect.Field.get(Field.java:379)
    at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39)
    ... 40 more
2016-06-08 13:06:53,232 [main            ] [          ] INFO  restx.monitor.MetricsConfiguration - registering Metrics JVM metrics

I have stepped through my program and it seems to have a valid object passed the the hibernate save function, and somewhere inside it throws an error. I have tried removing the created field, at which point it then complains about a string field with the same error, trying to set it as a Player object itself.

here is my DAOimpl.class

package centaurus.dao.user;

import centaurus.domain.User;

import centaurus.service.HibernateUtils;
import restx.factory.Component;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import javax.inject.Named;
import java.util.List;

@Component
public class UserDAOimpl implements UserDAO {
    private static HibernateUtils hibernateUtils;

    public UserDAOimpl(@Named("HibernateUtils") HibernateUtils hibernateUtils) {
        this.hibernateUtils = hibernateUtils;
    }

    public User saveUser(User user){
        Session session = hibernateUtils.getFactory().openSession();
        Transaction tx = null;
        Integer playerID = null;
        try{
            tx = session.beginTransaction();
            //playerID = (Integer) session.save(user);
            session.save(user);

            tx.commit();

        }catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        }finally {
            session.close();
        }
        return user;
    }

    public User getUser(int playerId){
        Session session = hibernateUtils.getFactory().openSession();
        try{
            User user = (User)session.get(User.class, playerId);
            return user;
        }catch (HibernateException e) {

        }finally {
            session.close();
        }
        return null;
    }

    public List<User> getUsers(){
        Session session = hibernateUtils.getFactory().openSession();
        List<User> list = null;
        try{
            list = session.createCriteria(User.class).list();

        }catch (HibernateException e) {

        }finally {
            session.close();
        }
        return list;
    }
}

I have googled and googled and tried as many hibernate tutorials as i can find and I still have this issue. I don't understand why hibernate is trying to set a field as an object, I have my annotations.

incase its wanted here is my domain object player:

package centaurus.domain;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

@Entity
@Table(name="users")
public class User implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="USER_ID")
    private int id = 0;

    @Column(name="EMAIL")
    private String email = "";

    @Column(name="CREATED")
    private Date created = null;

    public User(){
        Calendar cal = Calendar.getInstance();
        this.created = cal.getTime();
    };

    public User(int id, String email, Date created) {
        this.id = id;
        this.email = email;
        this.created = created;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", email='" + email + '\'' +
                ", created=" + created +
                '}';
    }
} 

and here is the calling class:

package centaurus;

import centaurus.dao.user.UserDAO;
import centaurus.domain.User;
import restx.factory.AutoStartable;
import restx.factory.Component;

import javax.inject.Named;


@Component
public class DBMaintain implements AutoStartable{
    private UserDAO userDAO;

    public DBMaintain(@Named("UserDAOimpl") UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public void start(){
        System.out.println("START SCRIPT!");

        //test
        User p = new User();
        p.setEmail("test");
        userDAO.saveUser(p);

    }
}

Please does anyone know how to solve this issue, thanks.

EDIT: (added sql)

CREATE TABLE Users(
    USER_ID int NOT NULL AUTO_INCREMENT,
    CREATED TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    EMAIL varchar(45) DEFAULT NULL,
    PRIMARY KEY (USER_ID)
);

EDIT added hibernate config /src/main/resources/hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection properties - Driver, URL, user, password -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/andromeda</property>
        <property name="hibernate.connection.username">api</property>
        <property name="hibernate.connection.password">apipassword</property>
        <!-- Connection Pool Size -->
        <property name="hibernate.connection.pool_size">1</property>

        <!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
        <property name="hibernate.current_session_context_class">thread</property>

        <!-- Outputs the SQL queries, should be disabled in Production -->
        <property name="hibernate.show_sql">true</property>

        <!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
            Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>


        <mapping class="centaurus.domain.User"/>
    </session-factory>
</hibernate-configuration>
like image 426
Arthur Avatar asked Jun 06 '16 11:06

Arthur


People also ask

What are Data Access Objects (daos)?

Data Access Objects (or DAOs for short) are used as a direct line of connection and communication with our database. DAOs are used when the actual CRUD (CRUD = Create, Read, Update, Delete) operations are needed and invoked in our Java code. These data access objects also represent the “data layer” of our application.

What is configuration object in hibernate?

This is the first object we use when using the Hibernate. This object is used to specify the location of a configuration file and mapping document used by Hibernate. Using Configuration object we can create a SessionFactory object, which is eventually used to create a Session object to perform the object persistence operations.

What are Java Hibernate objects?

These objects are still just plain old Java objects that incorporate the use of some Hibernate annotations to give them the functionality we need from them. Again, that functionality being the communication with the database.

Where are value type classes stored in hibernate?

This output shows that each object of Value Type class is stored as a part of an object of the Entity class, within a single database table. Note : The output clearly shows you that Hibernate has used its sequence object to generate the value of each primary key ( Id) automatically as we have used @GeneratedValue annotations with it.


1 Answers

Not sure if this is the answer but we will see!

Try replacing

CREATED TIMESTAMP DEFAULT CURRENT_TIMESTAMP

with

CREATED DATETIME DEFAULT CURRENT_DATETIME,

See the difference between Timestamp and Datetime in SQL is TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the current time zone for retrieval. (This occurs only for the TIMESTAMP data type, not for other types such as DATETIME.) If you store a TIMESTAMP value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored. TimeStamp MySQL

While DATETIME represents a date (as found in a calendar) and a time (as can be observed on a wall clock),

Since you cannot store Java Date into a SQL TIMESTAMP object, either change the SQL TIMESTAMP to DATETIME or change the

private Date created;

to

private Timestamp created;

//And convert your Date to TimeStamp
public User(){
    Date date = new Date();
    created = new Timestamp(date .getTime());
}

Hope this helps!

like image 141
Igoranze Avatar answered Sep 21 '22 16:09

Igoranze