-->
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: Self-referential many-to-one issue
PostPosted: Sat Dec 19, 2009 4:29 am 
Newbie

Joined: Tue Oct 20, 2009 5:06 am
Posts: 3
Hey folks, I'm currently trying to write some annotated POJOs to represent a database. The database is in SQLite, and I have no control over the formatting of the database.

For reference, I'm using Hibernate 3.3.2 GA, Hibernate EM 3.4.0 GA, and Hibernate Annotations 3.4.0 GA on Ubuntu 9.04 with Java 1.6.0_16.

My persistence.xml file is as follows:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
   <persistence-unit name="flashcards">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <properties>
         <property name="hibernate.archive.autodetection" value="class, hbm" />
         <property name="hibernate.show_sql" value="true" />
         <property name="hibernate.format_sql" value="true" />
         <property name="hibernate.connection.driver_class" value="org.sqlite.JDBC" />
         <property name="hibernate.connection.url" value="jdbc:sqlite:/home/ipsi/PlecoFlash.pqb" />
         <property name="hibernate.c3p0.min_size" value="5" />
         <property name="hibernate.c3p0.max_size" value="20" />
         <property name="hibernate.c3p0.timeout" value="300" />
         <property name="hibernate.c3p0.max_statements" value="50" />
         <property name="hibernate.c3p0.idle_test_period" value="3000" />
         <property name="hibernate.dialect" value="flashcard_manager.main.hibernate.dialects.SqliteDialect" />
      </properties>
   </persistence-unit>
</persistence>



My POJO looks like this:

Code:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

@Entity(name = "pleco_flash_categories")
@NamedQuery(name = "PFCats.Select", query = "Select pfcats from pleco_flash_categories pfcats")
@Data
public class PlecoFlashcardCategories
{

   @Setter(AccessLevel.PACKAGE)
   @Id
   @Column(unique = true)
   private int                     id;

   private String                  name;

   @Column(name = "created")
   private int                     createdDts;

   @Column(name = "modified")
   private int                     modifiedDts;

   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name = "parent")
   private PlecoFlashcardCategories   parent;

   private int                     sort;

   private int                     hidden;

   @Column(name = "class")
   private int                     clazz;
}


The Database itself is the Flashcard database created by the PlecoDict application. Also, I'm using Project Lombok to generate the Getters and Setters, which is why they're not displayed above.

The problem I'm having is that, when attempting to load the above POJO with the following code
Code:
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("flashcards");
      EntityManager em = emf.createEntityManager();
      List< ? > results = em.createNamedQuery("PFCats.Select").getResultList();
      for(Object o : results)
         System.out.println(o);


I get the following output

Code:
Hibernate:
    select
        plecoflash0_.id as id0_,
        plecoflash0_.class as class0_,
        plecoflash0_.created as created0_,
        plecoflash0_.hidden as hidden0_,
        plecoflash0_.modified as modified0_,
        plecoflash0_.name as name0_,
        plecoflash0_.parent as parent0_,
        plecoflash0_.sort as sort0_
    from
        pleco_flash_categories plecoflash0_
Hibernate:
    select
        plecoflash0_.id as id0_1_,
        plecoflash0_.class as class0_1_,
        plecoflash0_.created as created0_1_,
        plecoflash0_.hidden as hidden0_1_,
        plecoflash0_.modified as modified0_1_,
        plecoflash0_.name as name0_1_,
        plecoflash0_.parent as parent0_1_,
        plecoflash0_.sort as sort0_1_,
        plecoflash1_.id as id0_0_,
        plecoflash1_.class as class0_0_,
        plecoflash1_.created as created0_0_,
        plecoflash1_.hidden as hidden0_0_,
        plecoflash1_.modified as modified0_0_,
        plecoflash1_.name as name0_0_,
        plecoflash1_.parent as parent0_0_,
        plecoflash1_.sort as sort0_0_
    from
        pleco_flash_categories plecoflash0_
    left outer join
        pleco_flash_categories plecoflash1_
            on plecoflash0_.parent=plecoflash1_.id
    where
        plecoflash0_.id=?
Exception in thread "main" javax.persistence.EntityNotFoundException: Unable to find flashcard_manager.main.dao.PlecoFlashcardCategories with id -2
   at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:113)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:171)
   at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
   at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:906)
   at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:874)
   at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
   at org.hibernate.type.EntityType.resolve(EntityType.java:412)
   at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
   at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
   at org.hibernate.loader.Loader.doQuery(Loader.java:752)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
   at org.hibernate.loader.Loader.doList(Loader.java:2232)
   at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
   at org.hibernate.loader.Loader.list(Loader.java:2124)
   at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:401)
   at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
   at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1149)
   at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
   at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:67)
   at flashcard_manager.main.dao.PlecoFlashCards.main(PlecoFlashCards.java:69)


Now, I know *why* I'm getting that output - it's because, rather than use, say, a null Value when indicating that a given row does not have a parent row, it uses -2...

e.g.
Code:
id      name             created        modified       parent sort   hidden   class
"19"   "NPCR"            "1224317683"   "1224320048"   "-2"   "3"   "0"      "NULL"
"20"   "NPCR Book 1"     "1224317684"   "1224320049"   "19"   "1"   "0"      "NULL"
"21"   "NPCR 1"          "1224317684"   "1224317684"   "20"   "1"   "NULL"   "NULL"
"22"   "NPCR Text One"   "1224317684"   "1224320049"   "-2"   "4"   "0"      "NULL"


Now, from these rows, we can see that row 21's parent is row 20, with row 20's parent being row 19, and row 19 having no parent. Row 22 also has no parent. So, ideally, when loading my classes I should have a tree something like this:

Code:
Row 19.parent
   |--> Row 20.parent
            |--> Row 21.parent
                     |--> null


However, I've got no idea how to make that happen. Suggestions would be most welcome.

EDIT: Changing all instances of -2 as parent in the database to NULL solves the problem, oddly enough. So how do I tell Hibernate that -2 is actually equivalent to null?

Thanks,

- Andrew


Top
 Profile  
 
 Post subject: Re: Self-referential many-to-one issue
PostPosted: Sat Dec 19, 2009 4:52 am 
Newbie

Joined: Tue Oct 20, 2009 5:06 am
Posts: 3
Solved, I think: Just needed to add the @NotFound(action=NotFoundAction.IGNORE) annotation to the parent field. It generates more SELECTs than I would like, but since it's only a single DB on my local filesystem, I don't think that's particularly important.

EDIT: That's still not ideal, as I would like it to only ignore the "can't find mapping" issue when the parent field is equal to -2, but it's still a major improvement.


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.