-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Implementing a UserType
PostPosted: Mon Jul 13, 2015 5:36 am 
Newbie

Joined: Mon Jul 13, 2015 4:57 am
Posts: 2
Hi all!
I am trying to implement a custom usertype (org.hibernate.usertype.UserType) to use with my entities and am getting a GenericJDBCException. This is really frustrating. I hope someone can give me some pointers or good tutorials. Thnx

Trying to accomplish:
MyEntity.<MyType>listOfMyTypes;

When flushing session:
org.hibernate.exception.GenericJDBCException: could not insert collection: [foo.bar.TableEntity.listOfMyTypes#20001950] SQL: insert into TABLE_listOfMyTypes (TABLE_ID, MYTYPE_LIST) values (?, ?)
at ...
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1205)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:171)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)

I do not understand why this is happening. MyType should be a data type to be used by many different entities and is not an entity by it self. The SQL in the error message is suggesting that it is trying to insert each type into the database (but it should only be one column in one entity). The generated sql has severel flaws as there is no table called TABLE_listOfMyTypes. There is however a TABLE with a column called MY_TYPES. The name listOfMyTypes is the entity variable.

What is really bothering me is that before this exception is coming, myUserType is hardly used. What happens is that during loading of the hibernate context, the sqlTypes-method is invoked. Just before the exception, the deepCopy-method is invoked. The nullSafeSet-method that should produce the String for the databse is NOT invoked.

My field:
Code:
    @javax.persistence.Column(name = "MYTYPE_LIST", nullable = true)
    @org.hibernate.annotations.CollectionOfElements
    @org.hibernate.annotations.Type(type = "foo.bar.MyUserType")
    private List<foo.bar.MyType> listOfMyTypes = new ArrayList<foo.bar.MyType>();

MyUserType
Code:
public class MyUserType implements UserType {
    @Override
    public Object assemble(Serializable cached, Object owner) {
        return cached;
    }

    @Override
    public Serializable disassemble(Object value) {
        return (Serializable) value;
    }

    @Override
    public boolean equals(Object x, Object y) {
        return x.equals(y);
    }

    @Override
    public Object deepCopy(Object value) {
        return value;
    }

    @Override
    public int hashCode(Object x) {
        return x.hashCode();
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
        return foo.bar.MyType.createListFrom(rs.getString(names[0])); // this bag is only mapped to one column
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException {
        if (value == null) {
            st.setNull(index, Types.VARCHAR);
        }

        st.setString(index, foo.bar.MyType.createStringFrom(value));
    }

    @Override
    public Object replace(Object original, Object target, Object owner) {
        return original;
    }

    @Override
    public Class returnedClass() {
        return foo.bar.MyType.class;
    }

    @Override
    public int[] sqlTypes() {
        return new int[] {
                Types.VARCHAR
        };
    }
}

Versions:
<hibernate-annotations.version>3.4.0.GA</hibernate-annotations.version>
<hibernate-commons-annotations.version>3.1.0.GA</hibernate-commons-annotations.version>
<hibernate-ehcache.version>3.3.1.GA</hibernate-ehcache.version>


Top
 Profile  
 
 Post subject: Re: Implementing a UserType
PostPosted: Mon Jul 13, 2015 9:32 am 
Newbie

Joined: Mon Jul 13, 2015 4:57 am
Posts: 2
I have simplified my code a little bit. I am now having a one-to-one relationship for my types vs. a list of types:
Quote:
Code:
   @javax.persistence.Column(name = "MYTYPE_LIST", nullable = true)
   @org.hibernate.annotations.Type(type = "foo.bar.MyUserTypes")
   private foo.bar.MyTypes myTypes;

...

   public class MyUserTypes implements UserType {
...
    @Override
    public boolean isMutable() {
        return true;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
        return MyTypes.createFrom(rs.getString(names[0])); // this bag is only mapped to one column
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException {
        if (value == null) {
            st.setNull(index, Types.VARCHAR);
        }

        st.setString(index, MyTypes.createStringFrom(value));
    }

The exception type is still the same, but I know get a different sql (which looks correct). Again hibernate invokes the deepCopy-method on my user type, but nullSafeSet-method are never invoked


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.