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