-->
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.  [ 8 posts ] 
Author Message
 Post subject: many-to-one relationship without PK and FK in Database
PostPosted: Fri Aug 10, 2007 12:45 pm 
Beginner
Beginner

Joined: Mon Nov 13, 2006 9:43 am
Posts: 30
Hi gurus,

Mapping documents:

Code:
<class name="de.tsystems.fbs3.hibernate.bean.Fbs3LogEntry"  table="LOG_VIEW">
     ...
     <property name="logUserId" column="LOG_USER_ID"/>
     ...
</class>

Code:
<class name="de.tsystems.fbs3.hibernate.bean.User" table="USER"
      dynamic-update="true"
      dynamic-insert="true"
   >
     <id name="id" column="USR_ID">
        <generator class="identity"/>
     </id>
      ...
<property name="slvId" column="USR_SLV_ID"/>
      ...
</class>


LOG_VIEW is a database view and there is no relationship between it's table and table USER.

I'm implementing a web application and on the page with the list of entries from LOG_VIEW, on mouseOver event I have to show some user info for each log entry. I thought the best way would be to retrieve these infos on querying LOG_VIEW. In "normal life" I would just join them and get user as second alias. But how to join them in hibernate without having FK/PK stuff???

I have tried few solutions but they didn't work. And I could'n find anywhere any valuable info...

I can't imagine that it can not be done in hibernate...

Many thanks in advance,

giorgi


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 11, 2007 2:47 am 
Newbie

Joined: Sat Oct 28, 2006 6:16 am
Posts: 17
I am assuming that you don't wish to have an association between Fbs3LogEntry and User. That is you don't want to have a property on Fbs3LogEntry that returns the associated User. E.g. you don't want:

Code:
class Fbs3LogEntry {
...
    public User getUser() { ...
...
}


If that is the case and also assuming that every fbs3LogEntry has an associated User then the following HQL query might be what you are looking for:

Code:
select fbs3LogEntry, user from Fbs3LogEntry as fbs3LogEntry, User as user where user.id = fbs3LogEntry.slvId


This will return a list of Object[2] (Object arrays of size 2). See
http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#objectstate-querying-executing-tuples for an example of code that uses a similar query result.

Information about the HQL where clause is at http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#queryhql-where


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 11, 2007 4:38 pm 
Beginner
Beginner

Joined: Mon Nov 13, 2006 9:43 am
Posts: 30
Hello simon_t,

thanks for your answer!

Quote:
>I am assuming that you don't wish to have an association between Fbs3LogEntry and User.

In the Database - no, but in Hibermate - with pleasure!!! I would like to have
Code:
class Fbs3LogEntry {
...
    public User getUser() { ...
...
}

It would make very easy to create HQ with join.

But it means having many-to-one relationship in mapping and exactly this is what I can't make to work without FK -> PK on the database layer...
So my main problem is to define many-to-one(one-to-many) relationship in hibernate mapping without using PK of parent and FK of child but 2 "simple" fields from both sides.

As about second solution - I'll try it for sure on monday and let you know.

Best regards,

giorgi


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 13, 2007 1:52 am 
Beginner
Beginner

Joined: Mon Nov 13, 2006 9:43 am
Posts: 30
Hello,

no, it's will not work for me. Reason:
There are some entries in Fbs3LogEntry for users that don't exist in User table. So using this kind of query they will be lost.
My idea was to be able to get(somehow) query like
Code:
from de.tsystems.fbs3.hibernate.bean.Fbs3LogEntry as logEntry left join  logEntry.user as usr

by defining many-to-one(one-to-many) in mappings. And of course having also appropriate getters and setters...

I'm just wondering, as I can do in DB following:
Code:
SELECT * FROM Fbs3LogEntry log
LEFT OUTER JOIN User usr ON log.LOG_USER_ID = usr.SLV_ID

when User.SLV_ID is no a primary key and Fbs3LogEntry.LOG_USER_ID is no foreign key referencing it why can't it be possible to do the same in hibernate using HQL...

Anyway, I have some emergency solutions.

Or may be someone has another creative idea?

Many thanks and regards,

giorgi


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 15, 2007 12:04 am 
Newbie

Joined: Sat Oct 28, 2006 6:16 am
Posts: 17
I understand more about your problem now.

There is something that may help you, here: http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html#mapping-declaration-manytoone. Specifically the not-found option for many-to-one. It determines the behaviour when the foreign id column contains an id that corresponds to no object:

Quote:
not-found (optional - defaults to exception): Specifies how foreign keys that reference missing rows will be handled: ignore will treat a missing row as a null association.


So if you have Fbs3LogEntry.getUser() then in the mapping if you set the not-found option to ignore then for all Fbs3LogEntrys that reference a user that does not exist Fbs3LogEntry.getUser() will return null.

With this will it be possible?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 1:59 am 
Beginner
Beginner

Joined: Mon Nov 13, 2006 9:43 am
Posts: 30
Hi,

thanks for reply.

I came across to that feature when looking for solution, but in that case you are not able to show LOG_USER_ID of Fbs3LogEntry on the screen as you don't have it defined as property anymore
Code:
<property name="logUserId" column="LOG_USER_ID"/>


because it participates in many-to-one relation - it should be removed from the list of properties otherwise you get some kind of "can not parse property file..." error during deployment.

So only way to retrieve that value is to do Fbs3LogEntry.getUser().getSlvId(). But User is NULL so you will never get that field for the cases like described in this issue.

Attribute "not-found" of many-to-one relationship sounds Pretty good but I'm not sure I understand how it works. It can only be used in "pseudo"-relationships (I mean many-to-one defined only in hibernate without having FK->PK in DB). And exactly this question (how to define these "pseudo"-relationships in hibernate) is still opened for me...

Or may be I'm understanding everything wrong :-)

Regards,

giorgi


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 7:37 am 
Newbie

Joined: Sat Oct 28, 2006 6:16 am
Posts: 17
I think hibernate will let you have two properties mapping to the same column. So in your case you can have something like the following:

Code:
class Fbs3LogEntry {
...
    public User getUser() { ...
...
    public int getLogUserId() {...
...
}


I might be putting you wrong but I think it is worth a try. You will probably want to set update=false and insert=false for the getUser property to save hibernate getting confused when inserting or updating (without it Hibernate might even set LOG_USER_ID to null if the user does not exist).

As far as I know Hibernate was designed to handle mapping to legacy data. I expect that options like "not-found" exist to provide the flexibility for this.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 8:37 am 
Beginner
Beginner

Joined: Mon Nov 13, 2006 9:43 am
Posts: 30
Hi,

no, you are not putting me wrong - one head is good but two are better(not always, but in this case that's true:-))

So, I had typing errors everywhere where it was possible :-). The hibernate is throwing no exceptions.
In mapping of User Bean:

Code:
<set name="logEntries" inverse="true" lazy="true"  cascade="save-update">
           <key column="LOG_USER_ID"/>
           <one-to-many class="de.tsystems.fbs3.hibernate.bean.Fbs3LogEntry"/>
</set>


In Fbs3LogEntry:

Code:
<many-to-one name="user" class="de.tsystems.fbs3.hibernate.bean.User" column="slvId" not-null="false" insert="false" update="false" not-found="ignore"/>


Actually I don't need to do user.getLogEntries() but I have no idea how can I tell hibernate to map these 2 beans exactly with fields that I want.

I have already implemented another solution so this issue is the metter of interest and also for future purposes, of course.

Regards,

giorgi


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