Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » @JoinColumn @Convert(Any way to tweak the way @JoinColumn treats foreign keys?)
icon5.gif  @JoinColumn @Convert [message #1083663] Sat, 10 August 2013 09:04 Go to next message
Peer  Törngren is currently offline Peer TörngrenFriend
Messages: 14
Registered: July 2009
Location: Sweden
Junior Member
Is there some way to modify the way a @JoinColumn handles foreign keys for null fields? I think I'm looking for something like a @Convert that I can apply to the @JoinColumn, similar to how I can apply @Convert to @Column.

More specifically, what I need to do is to convert a DB field with all spaces to null when reading, and convert a entity field that is null to all spaces when writing, but let the join behave normally in all other cases (i.e. look up and return the entity instance with the referenced id).

New to JPA and EclipseLink, hope there is a simple and obvious answer?

Background:

Trying to join a simple entity (A) to another entity (B) using a plain join and a single field key in a legacy DB.

Problem is that the DB schema states all fields as NOT NULL, using spaces to indicate an absent key. This works just fine when writing native SQL, but I have problems doing this with a JPA mapping. Since this concerns a legacy DB with lots of manual SQL based on these conventions, changing the DB schema is not an option.

Using a plain @JoinColumn seems to work ok when I read entity A, since it fails to find an entity B with all spaces as key (albeit presumably with some cost for trying to look it up), and entity A is loaded with null in the field for entity B.

But when I try to write entity A (insert or update) I get errors complaining about trying to insert null into not nullable field for B in table A.

Simple illustration - READ:

TableA
id, fkB (NOT NULL)
'A1', 'B1'
'A2', ' '

TableB
id
'B1'

Desired result when loading entities from TableA:
a1.b: b1
a2.b: null

Simple illustration - WRITE:

a1.b: b1
a2.b: null

Desired result when writing entities to TableA:

TableA
id, fkB (NOT NULL)
'A1', 'B1'
'A2', ' '

TableB
id
'B1'

[Updated on: Sat, 10 August 2013 09:09]

Report message to a moderator

Re: @JoinColumn @Convert [message #1083668 is a reply to message #1083663] Sat, 10 August 2013 09:14 Go to previous messageGo to next message
Peer  Törngren is currently offline Peer TörngrenFriend
Messages: 14
Registered: July 2009
Location: Sweden
Junior Member
This message about Converters for non-basic types seems to be similar?

[Updated on: Sat, 10 August 2013 09:16]

Report message to a moderator

Re: @JoinColumn @Convert [message #1085870 is a reply to message #1083668] Tue, 13 August 2013 13:35 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Sounds like your data model is not correct. If a relationship can be null, the foreign key should be nullable.

James : Wiki : Book : Blog : Twitter
Re: @JoinColumn @Convert [message #1087904 is a reply to message #1085870] Fri, 16 August 2013 08:58 Go to previous messageGo to next message
Peer  Törngren is currently offline Peer TörngrenFriend
Messages: 14
Registered: July 2009
Location: Sweden
Junior Member
One may have an opinion about the design of the DB schema (and it is not mine Smile, but as stated above - since this concerns a legacy DB with lots of manual SQL based on these conventions, changing the DB schema is not an option.

I did however find a way of handling this - almost Sad

I use @Basic and @Convert annotations with a custom converter that converts between object value and data value. Simple example:

@Converter(name="myConverter", converterClass=MyConverter.class),
public class MyEntity {

    @Convert("myConverter")
    @Basic(fetch=FetchType.LAZY, optional=true)
    private MyOtherEntity counterCompany;
}


This works fine and maps objects back and forth as desired. However, I cannot get the LAZY fetch to work (I do weaving, and lazy fetch on @ManyToOne mappings work just fine). Considering how some of these objects are used, LAZY fetch is crucial for decent performance.

So I guess the question would be slightly modified:
1 - is there a good reason for my converter being called on load despite @Basic(fetch=FetchType.LAZY)?
2 - is there some other way to do this (could a DescriptorCustomizer help me?)
Re: @JoinColumn @Convert [message #1090520 is a reply to message #1087904] Tue, 20 August 2013 08:51 Go to previous messageGo to next message
Peer  Törngren is currently offline Peer TörngrenFriend
Messages: 14
Registered: July 2009
Location: Sweden
Junior Member
About Q1:

"@Basic
TopLink JPA ignores the fetch attribute. Default FetchType.EAGER always applies."
(http://www.oracle.com/technetwork/middleware/ias/toplink-jpa-extensions-094393.html#LazyLoading)

But on the other hand:
"Use the @Basic annotation to do the following:
configure the fetch type to LAZY;"
(http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Basic)

Still a mystery to me. Anyone else seeing this problem?
Re: @JoinColumn @Convert [message #1095792 is a reply to message #1090520] Tue, 27 August 2013 14:26 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1389
Registered: July 2009
Senior Member
What product and version are you using? EclipseLink supports lazy basics through fetch groups which require weaving to enhance your entities : http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving

Best Regards,
Chris


Re: @JoinColumn @Convert [message #1095894 is a reply to message #1095792] Tue, 27 August 2013 17:30 Go to previous message
Peer  Törngren is currently offline Peer TörngrenFriend
Messages: 14
Registered: July 2009
Location: Sweden
Junior Member
Chris Delahunt wrote on Tue, 27 August 2013 16:26
What product and version are you using? EclipseLink supports lazy basics through fetch groups which require weaving to enhance your entities : http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving

Best Regards,
Chris




I'm using 2.5.0, and I do static weaving that works just fine for regular @JoinColumn mappings mappings (e.g. @ManyToOne).

What do you mean by "through fetch groups" - is there something I need to do to get @Basic to do lazy fetch that I don't have to do for more "sophisticated" mappings?

N.B. I'm doing static weaving, running resource-local POJOs (not server managed), if it matters.

[Updated on: Tue, 27 August 2013 20:01]

Report message to a moderator

Previous Topic:ReadOnly mapping attribute causes inserts
Next Topic:Jpa UNION and MySql
Goto Forum:
  


Current Time: Thu Apr 25 14:22:41 GMT 2024

Powered by FUDForum. Page generated in 0.03822 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top