-->
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.  [ 5 posts ] 
Author Message
 Post subject: Problem binding a property which is a foreign key
PostPosted: Thu Aug 21, 2008 2:11 am 
Newbie

Joined: Thu Aug 21, 2008 1:41 am
Posts: 3
I've read the Hibernate manual, annotation guide, books, but I have not found any single exemple which does what I would like to do so I am posting it here.

The problem seems to me quite simple. I have 2 classes, something like this:

class A {
List<B> bList;
long pk; // Primary Key
...
}

class B {
long pk;
long fId; // Foreign key to class A.pk
...
}

with getters and setters.

How do you bind the field fId to class A.pk? All exemples I have seen always do bindings using the whole class, not a field. Is it possible to do it this way? I don't see why this should not be an easy thing to do, and why I can't even find a single exemple.

Thanks for your help,
Llaurick


Top
 Profile  
 
 Post subject: Re: Problem binding a property which is a foreign key
PostPosted: Thu Aug 21, 2008 2:47 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
llaurick wrote:
class A {
List<B> bList;
long pk; // Primary Key
...
}

class B {
long pk;
long fId; // Foreign key to class A.pk
...
}

with getters and setters.

How do you bind the field fId to class A.pk? All exemples I have seen always do bindings using the whole class, not a field. Is it possible to do it this way? I don't see why this should not be an easy thing to do, and why I can't even find a single exemple.

Llaurick


Indeed, you can do it as you've done it and Hibernate will load your foreign key just as a simple primitive attribute. If you do it like this, then you have no real Object relationship between A and B and you've lost one of the nice features which an ORM does automatically for you: load the corresponding table row represented by the foreign key and return the object representing it.

Well, sometimes, you may wish to not let resolve such a foreign key relationship by the ORM tool - I have such a case in my app. Then, of course, you have to manually load the object represented by it's id and you have to declare a @Transient member A in your class B which you must manually set after loading it from the DB (if you don't want to loose your object association. Your code then should be like this:

Code:
class B {
   @Id
   long pk;

   @Column (name="FK_TO_A")
   long fId;

   @Transient
   A a;
....
}


But a case should be an exception - after all, why did decide to use an ORM tool?

_________________
Carlo
-----------------------------------------------------------
please don't forget to rate if this post helped you


Top
 Profile  
 
 Post subject: Re: Problem binding a property which is a foreign key
PostPosted: Fri Aug 22, 2008 12:17 am 
Newbie

Joined: Thu Aug 21, 2008 1:41 am
Posts: 3
Thanks for the answer.
If I understand, what you're saying is that if I want hibernate to be able to do a binding, I need to refer to the whole object?

I was trying to do a binging that way because in fact I have a bigger problem I am trying to solve, which is a performance problem, and no mather how I try, I always get something which does not work.

To give you a more concrete exemple, I have a table DataFile containing info about files. Those files contain mathematical data for pattern recognition. Each file contains around 300 data which are read from the file and written in table Fp . So for each entry in table DataFile, there will be around 300 in table Fp.

Table Fp is very very big, and we want it to be as fast as possible, and not need any join in queries. Because performance is critical, we've been testing using MySQL with a MYIsam DB with no foreign key enforced nowhere. Only indexes. And because the data manipulation for writing is very straightforward and simple, the database (and Hibernate) is not transactional neither.

And the problem I have been having is that when I try to insert the content of a file, I get 300 insert on table Fp.

The first code I did was this: (We are using Hibernate with Spring)

Code:
public void insertData(List<Long> datas, Long fId) {
  HibernateTemplate hibTemplate = this.getHibernateTemplate();
  for(Long data: datas) {
    Fp fp = new Fp(data, fId);
    hibTemplate.persist(fp);
  }
}


I knew, of course, with this I would not get bulk insert, but I wanted a working code first.

I though that by putting a collection of Fp in the class DataFile, filling the content of the collection and calling persist on class DataFile, Hibernate would do batch insert for the Collection. But to be able to set the fId in the class Fp, I need first to persist DataFile without the collection of Fp datas to get the value for fId. The code looks like this:

Code:
DataFile df = new DataFile();
// ... sets other attributes
getHibernateTemplate().persist(df);
List<Fp> fps = getFpList(file, df.getId()); // gets the list of data from file
df.getFps().addAll(fps);
getHibernateTemplate.saveOrUpdate(df); // I've tried with persist too.


But this does not work. I get the following error message:
java.sql.BatchUpdateException: failed batch.

Another way I've tried is to map a collectionOfElements, and not use a Fp class at all. There is no other attribute in the Fp class so this is possible. The class DataFile contains the following annotation:

Code:
@CollectionOfElements
@JoinTable(name="Fp", joinColumns = @JoinColumn(name="fId"))
@Column(name="data", nullable=false)
public List<long> getFpData()


If I completly remove the class Fp (so no entity class is declared on table Fp), This does in fact works, even if it creates a table Fp without a pk (I've let Hibernate generate the schema to see). I can create all the data, do one persist and I presume Hibernate is able to do bulk inserts.

But it does break a custom query on the Fp table, which I have not been able to modify to work with this way of mapping. The query looks like this:

Code:
@NamedQuery(name="searchData",
query="select new com.xyz.SearchData(fp.fId, count(fp) from Fp fp where fp.fId in (:fpList) group by fp.fId order by count(fp) desc)


How do I write this query if I don't have an entity class Fp?

Thanks for your help,

Llaurick


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 22, 2008 5:52 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
It's easy, if you have no FP entity: just use a NativeQuery with plain SQL.

_________________
Carlo
-----------------------------------------------------------
please don't forget to rate if this post helped you


Top
 Profile  
 
 Post subject: Re: Problem binding a property which is a foreign key
PostPosted: Mon Aug 25, 2008 3:23 pm 
Newbie

Joined: Thu Aug 21, 2008 1:41 am
Posts: 3
carlolf wrote:
It's easy, if you have no FP entity: just use a NativeQuery with plain SQL.


I had tried doing this. The problem I got is that the class SearchData, which is used to map the ResultSet, is not an Entity class. It's a DTO. It does not map to any table. I have written it this way:

Code:
@NamedNativeQuery(name="searchData",
   query="select fId, count(fId)) " +
         "from Fp where fId in ( :fpList ) GROUP BY fId ORDER BY count(fId) DESC")
@SqlResultSetMapping(name="searchResult", entities = {
   @EntityResult(entityClass = com.xyz.SearchData.class, fields = {
      @FieldResult(name = "fId", column = "fId"),
      @FieldResult(name = "count", column = "count")
   })
})


But I get this error:

org.hibernate.cfg.NotYetImplementedException: Pure native scalar queries are not yet supported

Does this mean that I need to use ColumnResult instead in the annotation and iterate through the result to create the SearchData objects?


Llaurick


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.