Win a copy of Micro Frontends in Action this week in the Server-Side JavaScript and NodeJS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Paul Clapham
  • Bear Bibeault
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • salvin francis
  • Scott Selikoff
  • fred rosenberger

Bidirection join broken in one direction?

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm currently grappling with converting an app which used JDBC and handcoded SQL to Hibernate so it's more robust/scaleable (in theory, this has proven to be a nightmare!). Due to it being a conversion job which was itself an enhancement of a previous application, a legacy database is involved, and the database schema is actually broken.

The problem I have is this. And apologies for the wordiness for what is I suspect a very simple problem but I figure the more you know the easier to answer.

I have a Transmitter object, which is persistent.

I also have a TransmitterLocation object, which is persistent.

There exists a one to one relationship between them. (Seems a bit odd maybe to have the location as a separate object, but there is a potential option to have transmitters with multiple locations in the future, and they did have them in the past. For now, however, it is a one-to-one relationship, which is why I say the schema is broken - there is no such constraint at the SQL level. The joy of legacy databases... Although the Java front end is coded in such a way that this constraint should never be broken anyway.).

Note that not every Transmitter has a TransmitterLocation, though every TransmitterLocation must have a transmitter.


Here are some Hibernate annotations so you can see the mapping.

public class Transmitter {
@Id
@GeneratedValue
@Column(name = "TX_ID")
private int txId;

@OneToOne (optional = true)
@JoinColumn (name = "TX_ID", referencedColumnName = "TX_ID")
private TransmitterLocation loc;

.....
}

public class TransmitterLocation {

@Id @GeneratedValue
@Column (name = "TX_PLANPLACE_ID")
private int id;

@OneToOne (optional = false)
@JoinColumn (name = "TX_ID")
private Transmitter tx;

....
}

The DB schema is pretty straightforward, TX_PLANPLACE was and may be again a join table...

Table TX
TX_ID (primary key) blah blah blah

Table TX_PLANPLACE
TX_PLANPLACE_ID (primary key) TX_ID (foreign key) blah blah blah


In the initialisation code I have...

locs = s.createQuery("from TransmitterLocation").list();
transmitters = s.createQuery("from Transmitter").list();

The problem is that the join, while supposedly bidirectional, is not. After running that initialisation code, from a given TransmitterLocation I can get to a Transmitter. However, from a Transmitter, if I call getTransmitterLocation, it returns null - even if a TransmitterLocation exists.

So only one direction of the relationship is being modelled - something is wrong with the annotation in the Transmitter class. Oddly enough when saving the TransmitterLocation objects everything seems fine, it doesn't throw any exceptions and the database matches what was in memory. It is when recalling persisted objects that things come apart.

Any help on this out there?
 
Ranch Hand
Posts: 84
Hibernate Eclipse IDE Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Rob, i think the problem it's the mapping itself, not that the Bidirection join it's broken.

When dealing with bidirectional mapping you should only map one of the sides with the attribute mappedBy, this will make the mapping a lot easier because it will configure accordingly to the inverse mapping avoiding any distinct configuration on any one of the sides.

Also there in the mapping you have an error in the referenceColumnName attribute. This value must be the name of the property on the inverse entity not the column name of the inverse entity, meaning that the correct value must be id not TX_ID.

This suggest the following mapping:



regards,
 
Rob Fry
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Angel Taveras:
When dealing with bidirectional mapping you should only map one of the sides with the attribute mappedBy, this will make the mapping a lot easier because it will configure accordingly to the inverse mapping avoiding any distinct configuration on any one of the sides.

Also there in the mapping you have an error in the referenceColumnName attribute. This value must be the name of the property on the inverse entity not the column name of the inverse entity, meaning that the correct value must be id not TX_ID.



Genius, this is it, it works now. I didn't realise mappedBy and referenceColumnName wanted Java attributes not SQL columns! Suddenly everything is much clearer, thanks.
 
The longest recorded flight time of a chicken is 13 seconds. But that was done without this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic