Avatar billede fredand Forsker
02. januar 2017 - 22:42 Der er 8 kommentarer og
2 løsninger

Problems with hibernate and collections

Hello guys!

We are migrating from:
Jboss 5.0 to Jboss 6.3
java 6 to java 7
ojdbc6_g-11.2.0.2.0.jar to ojdbc7_g-12.1.0.1.jar

In Jboss 6.3 we are getting this error:

Caused by: java.lang.RuntimeException: org.hibernate.exception.GenericJDBCException: could not initialize a collection: [com.company.AClass.bs#23]

I have also tried to use ojdbc6_g-11.2.0.2.0.jar, but we get the same error.
The strange thing is that this worked fine in Jboss 5.0 and I thought that it should work as fine in Jboss 6.3.
Below is some code snippets and the db-tables (with values) that are involved.
Do you guys got any idea what might is wrong?
Best regards
Fredrik


@Entity
@Table(name = "ACLASS")
public class AClass

    @Id
    @Column(name = "ID")
    private String    id;

    @Column(name = "NAME")
    private String    name;
   
    @JoinColumn(name = "FK_ACLASS_ID")
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<BClass>    bs;
   
    ...


@Entity
@Table(name = "BCLASS")
public class BClass {

    @Id
    @Column(name = "ID")
    String    id;

    @Column(name = "TYPE")
    Type    type;
   
    ...
   

public enum Type {

    A("a", "A"),
    B("b", "B"),
    C("c", "C"),
    D("d", "D"),
    E("e", "E"),
    F("f", "F");
   
    ...
   

The database tables

ACLASS
(AClass.java)

id VARCHAR2(32)
name VARCHAR2(64)

VALUES
1 name_1
2 name_2
3 name_3
4 name_4
5 name_5
6 name_6
7 name_7
8 name_8
9 name_9
10 name_10
11 name_11
12 name_12
13 name_13
14 name_14
15 name_15
16 name_16
17 name_17
18 name_18
19 name_19
20 name_20
21 name_21
22 name_22
23 name_23
24 name_24
25 name_25

   
BCLASS   
(BClass.java)

id VARCHAR2(32)
type VARCHAR2(1)
fk_aclass_id VARCHAR2(32)

VALUES
23a A 23
23b B 23
23c C 23
23e D 23
1  A 7
2  B 7
3  C 7
4  D 7
6  E 7
7  F 7
5  D 14   
Avatar billede arne_v Ekspert
03. januar 2017 - 01:10 #1
JPA with Hibernate as provider I assume.

How does setBs look like?
Avatar billede fredand Forsker
03. januar 2017 - 08:09 #2
Hello!
Yes the imports are like:

import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;


I never thought about those methods but of course those must be of interest!
How ever they do not look fishy to me:


    public Set<BClass> getBs() {
        return bs;
    }
   
    public void setBs(final Set<BClass> pBs) {
            bs = pBs;
    }
Avatar billede fredand Forsker
03. januar 2017 - 22:09 #3
Hello!

Today I thought that if I put a breakpoint in the setBs and getBs perhaps I would get an idea of what is going on, but unfortunately it did not stop on the breakpoint when I executed it so I guess the problem must be something deeper.

Any ideas of how to investigate this is most welcome.
Best regards
Fredrik
Avatar billede fredand Forsker
03. januar 2017 - 22:13 #4
Just wonder what the AClass.bs#23 refers to. In this case number 23 occurs at some places. Could it be something about row/id 23 in the table ACLASS?
Avatar billede arne_v Ekspert
04. januar 2017 - 02:55 #5
Are there another exception besides org.hibernate.exception.GenericJDBCException ?
Avatar billede arne_v Ekspert
04. januar 2017 - 03:05 #6
I am not a JPA guru, but I wonder about:

@JoinColumn(name = "FK_ACLASS_ID")
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)

I would have made that as:

@OneToMany(mappedBy = "nameOfFieldInBlassNotDatabaseColumn", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
Avatar billede fredand Forsker
04. januar 2017 - 22:14 #7
Hello!

First thanks for your time Arne!

Second, you might be right with your JPA suggestion, I will try it out of course. But since it worked in our old JBoss I guess it should work in our new JBoss.

Third I tracked down the call that gives the exception and with some extra catch I found a extra exception, as you already suspected!

final Query q = em.createNamedQuery(AClass.QUERY_FIND_ALL);
//@NamedQueries({@NamedQuery(name = "AClass.findAll", query = "SELECT r FROM AClass r")})
try
{
    @SuppressWarnings("unchecked")
    final List<AClass> list = q.getResultList();
    return list.toArray(new AClass[list.size()]);
}
catch(Exception ge)
{
    ge.printStackTrace();
    throw ge;
}


How ever the exception (see blow) looks a bit strange since it looks like hibernate/oracle-driver seems to try to read a int from some place. I'm not sure from where, but I guess it must be from some value of those in the first post above. In the database all these columns are Varchar2 of different length.


Caused by: org.hibernate.exception.GenericJDBCException: could not initialize a collection: [com.company.AClass.bs#23]
  at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
  at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)
  at org.hibernate.loader.Loader.loadCollection(Loader.java:2269)
  at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:65)
  at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:674)
  at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:
  at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1774)
  at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:696)
  at org.hibernate.engine.internal.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:1037)
  at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:353)
  at org.hibernate.loader.Loader.doList(Loader.java:2550)
  at org.hibernate.loader.Loader.doList(Loader.java:2536)
  at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2366)
  at org.hibernate.loader.Loader.list(Loader.java:2361)
  at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
  at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)
  at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:198)
  at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1194)
  at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
  at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:268)
  ... 283 more
Caused by: java.sql.SQLException: Kunde inte konvertera till intern representation
  at oracle.jdbc.driver.CharCommonAccessor.getInt(CharCommonAccessor.java:239)
  at oracle.jdbc.driver.T4CVarcharAccessor.getInt(T4CVarcharAccessor.java:601)
  at oracle.jdbc.driver.GeneratedStatement.getInt(GeneratedStatement.java:630)
  at oracle.jdbc.driver.GeneratedScrollableResultSet.getInt(GeneratedScrollableResultSet.java:1324)
  at oracle.jdbc.driver.GeneratedResultSet.getInt(GeneratedResultSet.java:3796)
  at org.jboss.jca.adapters.jdbc.WrappedResultSet.getInt(WrappedResultSet.java:1073)
  at org.hibernate.type.EnumType$OrdinalEnumValueMapper.getValue(EnumType.java:372)
  at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:107)
  at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:127)
  at org.hibernate.type.AbstractType.hydrate(AbstractType.java:106)
  at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2924)
  at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1695)
  at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1627)
  at org.hibernate.loader.Loader.getRow(Loader.java:1509)
  at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:719)
  at org.hibernate.loader.Loader.processResultSet(Loader.java:949)
  at org.hibernate.loader.Loader.doQuery(Loader.java:917)
  at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:348)
  at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:318)
  at org.hibernate.loader.Loader.loadCollection(Loader.java:2262)
  ... 300 more

Avatar billede arne_v Ekspert
05. januar 2017 - 01:12 #8
The getInt error is indeed puzzling.

I think you should try changing the annotations.
Avatar billede fredand Forsker
05. januar 2017 - 15:53 #9
Hello!

I hope managed to changed the annotation to use the mappedBy, how ever it turned out like this.

In AClass I changed the annoation to

@OneToMany(mappedBy = "aAClass", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<BClass>    bs;


In BClass it seamed that I had to add a field of ACLass to meet up the requirements for this relation.

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FK_ACLASS_ID")
AClass aAClass;


(I also added set and get methods for aAClass in BClass.)

But when I run it I get the same error:
   
...SQLException: Kunde inte konvertera till intern representation
at oracle.jdbc.driver.CharCommonAccessor.getInt(CharCommonAccessor.java:239)

Do you see any misstakes in the annotation?
Best regards
Fredrik
Avatar billede fredand Forsker
05. januar 2017 - 20:18 #10
Hello!

I think we found a solution after all Arne. With your help regarding looking for other exceptions I got the idea to google the net for: "CharCommonAccessor.getInt could not initialize a collection"
...which led me to:
http://stackoverflow.com/questions/26889015/every-time-i-think-i-fixed-it-could-not-initialize-a-collection-error-keeps-c
The solution found above turned out to be that I needed to add this annotation to the enumeration Type:


    @Enumerated(EnumType.STRING)
    @Column(name = "TYPE")
    Type    type;
 

After this change it worked fine. Really strange that we did not needed to use this in our former platform.

Tusind tak Arne for this discussion!

Best regards
Fredrik
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester