Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » many table, one entity, annotation driven?
many table, one entity, annotation driven? [message #377454] Fri, 01 August 2008 11:02 Go to next message
Kristian Rink is currently offline Kristian RinkFriend
Messages: 64
Registered: July 2009
Member
Folks;

maybe an utterly stupid question, nevertheless I lack a few pointers /
insights on that: In our (legacy) system, we do have sort of O/R mapping to
an SQL backend done in a way like this, assuming a class and its superclass:

- all "superclass" attributes go to a table "superclass" for any class to
extend "superclass",

- all "class" specific attributes, given "class" extends "superclass", go to
a "class" table specific to this class.

- Both tables do have a common key field (OBJID), for each row in "class"
table there is a corresponding row in "superclass" as well.

What I need / want to do now is using the features provided by JPA /
EclipseLink together with our RDBMS to, at best using annotations, read data
from the both of these tables to objects of one entity, like this:


public class NewsLetter extends Common {

private long id;

// life in table "common"
private String objName;
private String objDocument;

// life in table "newsletter"
private Date newsLetterDate;
private String newsLetterHeader;
private String newsLetterBody;

}


So far I dealt with modeling various ways of doing joins in JPA but the best
I came up with so far was fetching the content of table "common" to an
attribute "Common" in the newsletter class which would work but seems more
difficult than it needs to be.

So, question: Is there a way to map a JPA entity to two tables? Can this,
especially, be done using annotations? Am I overlooking something rather
simple, or is my conception flawed?

Thanks for any inspirations, best regards.
Kristian


--
Kristian Rink * http://zimmer428.net * http://flickr.com/photos/z428/ jab:
kawazu@jabber.ccc.de * icq: 48874445 * fon: ++49 176 2447 2771 "One dreaming
alone, it will be only a dream; many dreaming together is the beginning of a
new reality." (Hundertwasser)
Re: many table, one entity, annotation driven? [message #377455 is a reply to message #377454] Sat, 02 August 2008 00:49 Go to previous messageGo to next message
Michael Seidel is currently offline Michael SeidelFriend
Messages: 12
Registered: July 2009
Junior Member
Hi,

use a discriminator column and joined inheritance strategy.
For example:

@Entity
@Table(name="COMMON")
@DiscriminatorColumn(name="CAT", discriminatorType=DiscriminatorType.STRING)
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Common {
@Id
@GeneratedValue
private Long id;
@Column
private String objName;
@Column
private String objDocument;
...
}

@Entity
@DiscriminatorValue("NEWSLETTER") // Use any name you like
@Table(name="NEWSLETTER")
public class Newsletter extends Common {
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date newsletterDate;
@Column
private String newsletterHeader;
@Column
private String newsletterBody;
...
}

Michael
Re: many table, one entity, annotation driven? [message #377456 is a reply to message #377455] Mon, 04 August 2008 09:42 Go to previous messageGo to next message
Kristian Rink is currently offline Kristian RinkFriend
Messages: 64
Registered: July 2009
Member
Michael;

first off, thank you very much for pointing me here; seems a reasonable
solution after all and almost works in my environment, except for one
problem so far:

[...]
> @Inheritance(strategy=InheritanceType.JOINED)
> public abstract class Common {
> @Id
> @GeneratedValue
> private Long id;
[...]

Thanks to the database schema in our backend system (which is pretty strange
at times yet hard to change), the column "ID", table "Common", is used to be
called "RefId" in any other table. Straightforward I tried adding an @Id
@Column(name="RefId") to the class extending "Common" which, yet, ending in
a query that fails due to "Id" not found in the "Newsletter" table. Is
there, talking about JOINED, any way to, in the extending class, state which
column is to be used for the join?

Anyway, thanks again and best regards,
Kristian


--
Kristian Rink * http://zimmer428.net * http://flickr.com/photos/z428/ jab:
kawazu@jabber.ccc.de * icq: 48874445 * fon: ++49 176 2447 2771 "One dreaming
alone, it will be only a dream; many dreaming together is the beginning of a
new reality." (Hundertwasser)
Re: many table, one entity, annotation driven? [message #378581 is a reply to message #377456] Mon, 04 August 2008 17:32 Go to previous messageGo to next message
Michael Seidel is currently offline Michael SeidelFriend
Messages: 12
Registered: July 2009
Junior Member
Hi,

this is no problem, just add the PrimaryKeyJoinColumn annotation to the
class Newsletter.

@Entity
@DiscriminatorValue("NEWSLETTER")
@Table(name="NEWSLETTER")
@PrimaryKeyJoinColumn(name="IDREF")
public class Newsletter extends Common
{
...
}

In JPA there seems to be tinsel (ger: Lametta) for any kind of scary
database design. ;-)

Regards,
Michael

"Kristian Rink" <kawazu@zimmer428.net> schrieb im Newsbeitrag
news:g76ium$l3k$1@build.eclipse.org...
> Michael;
>
> first off, thank you very much for pointing me here; seems a reasonable
> solution after all and almost works in my environment, except for one
> problem so far:
>
> [...]
>> @Inheritance(strategy=InheritanceType.JOINED)
>> public abstract class Common {
>> @Id
>> @GeneratedValue
>> private Long id;
> [...]
>
> Thanks to the database schema in our backend system (which is pretty
> strange
> at times yet hard to change), the column "ID", table "Common", is used to
> be
> called "RefId" in any other table. Straightforward I tried adding an @Id
> @Column(name="RefId") to the class extending "Common" which, yet, ending
> in
> a query that fails due to "Id" not found in the "Newsletter" table. Is
> there, talking about JOINED, any way to, in the extending class, state
> which
> column is to be used for the join?
>
> Anyway, thanks again and best regards,
> Kristian
>
>
> --
> Kristian Rink * http://zimmer428.net * http://flickr.com/photos/z428/ jab:
> kawazu@jabber.ccc.de * icq: 48874445 * fon: ++49 176 2447 2771 "One
> dreaming
> alone, it will be only a dream; many dreaming together is the beginning of
> a
> new reality." (Hundertwasser)
Re: many table, one entity, annotation driven? [message #378583 is a reply to message #378581] Tue, 05 August 2008 06:17 Go to previous messageGo to next message
Kristian Rink is currently offline Kristian RinkFriend
Messages: 64
Registered: July 2009
Member
Hi Michael;

and, again, thanks for your input / information on that, much appreciated. :)

semi schrieb:
[...]
> @Entity
> @DiscriminatorValue("NEWSLETTER")
> @Table(name="NEWSLETTER")
> @PrimaryKeyJoinColumn(name="IDREF")
[...]
> In JPA there seems to be tinsel (ger: Lametta) for any kind of scary
> database design. ;-)

Hehe, pretty cool, tinsel to deal with questionable database design is right
what I am in dire need of, at the moment. Thanks bunches again for kicking
me the right direction. ;)

Cheerse & regds from DD/Germany,
Kristian

--
Kristian Rink * http://zimmer428.net * http://flickr.com/photos/z428/ jab:
kawazu@jabber.ccc.de * icq: 48874445 * fon: ++49 176 2447 2771 "One dreaming
alone, it will be only a dream; many dreaming together is the beginning of a
new reality." (Hundertwasser)
Re: many table, one entity, annotation driven? [message #378605 is a reply to message #378583] Wed, 06 August 2008 08:41 Go to previous messageGo to next message
Kristian Rink is currently offline Kristian RinkFriend
Messages: 64
Registered: July 2009
Member
Hi again;

speaking of "tinsel" and obscure database design:

Kristian Rink schrieb:
[...]
>> @Entity
>> @DiscriminatorValue("NEWSLETTER")
>> @Table(name="NEWSLETTER")
>> @PrimaryKeyJoinColumn(name="IDREF")
> [...]

While this approach (@DiscriminatorColumn / @DiscriminatorValue) does rather
well do in most situations (and, for that matters, makes migration of our DB
abstraction a rather pleasant procedure), I now have stumbled across a set
of situations in which this is not applicable, because, even though the
hierarchy is right the same (extending classes, common base class, separate
tables), there is no column usable as discriminator, leaving our backend
system obviously doing a simple join across the two tables using the common
ID, assuming the Discriminator is not required as "while the data is in the
'extending class' table, it per se must extend 'common' and thus have an
entry there". Which leaves me dealing with this... simply dumping the
@Discriminator* annotations, as supposed, broke my code again... Any way of
doing an inheritance hierarchy here without @Discriminator*? And, asides
that, any good books to be read on JPA dealing with these issues? Don't want
to steal anyones time...

Cheers & thanks for your patience,
Kristian

--
Kristian Rink * http://zimmer428.net * http://flickr.com/photos/z428/ jab:
kawazu@jabber.ccc.de * icq: 48874445 * fon: ++49 176 2447 2771 "One dreaming
alone, it will be only a dream; many dreaming together is the beginning of a
new reality." (Hundertwasser)
Re: many table, one entity, annotation driven? [message #378609 is a reply to message #378605] Wed, 06 August 2008 13:22 Go to previous messageGo to next message
James is currently offline JamesFriend
Messages: 272
Registered: July 2009
Senior Member
Some solutions are discussed here,

http://en.wikibooks.org/wiki/Java_Persistence/Inheritance#No _class_discriminator_column_2

The book has lots of info on inheritance in general and other persistence
topics.

Essentially in EclipseLink you can do it using a ClassExtractor and a
DescriptorCustomizer.

-- James
Re: many table, one entity, annotation driven? [message #379020 is a reply to message #378605] Wed, 06 August 2008 14:31 Go to previous message
Michael Seidel is currently offline Michael SeidelFriend
Messages: 12
Registered: July 2009
Junior Member
Hi,

there are two possible solutions for your problem.

* MappedSuperclass
* Embedable

But it's not the same as using discriminator columns. In both cases you no
more can do queries like "select c from Common c"

1a) MappedSuperclass with one common table

@MappedSuperclass
@Table(name="COMMON")
public abstract class Common {
@Id
@GeneratedValue
@Column
private Long id;
@Column
private String objName;
@Column
private String objDocument;
...
}

@Entity
@AttributeOverride(name="id", column=@Column(name="IDREF"))
public class Newsletter extends Common {
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date newsletterDate;
@Column
private String newsletterHeader;
@Column
private String newsletterBody;
...
}
------------------------------------------------------------ -----------------
1b) MappedSuperclass with the possibility to use different "base" tables
(see SecondaryTable annotation and AttributeOverrides)

@MappedSuperclass
public abstract class Common {
@Id
@GeneratedValue
@Column
private Long id;
@Column
private String objName;
@Column
private String objDocument;
...
}

@Entity
@SecondaryTable(name="COMMON",
pkJoinColumns=@PrimaryKeyJoinColumn(name="ID"))
@AttributeOverrides({
@AttributeOverride(name="objName", column=@Column(name="OBJNAME",
table="COMMON"))
,@AttributeOverride(name="objDocument",
column=@Column(name="OBJDOCUMENT", table="COMMON"))
})
@AttributeOverride(name="id", column=@Column(name="IDREF"))
public class Newsletter extends Common {
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date newsletterDate;
@Column
private String newsletterHeader;
@Column
private String newsletterBody;
...
}

------------------------------------------------------------ -----------------
2) Embedable in a common table

public interface ObjectInfoProvider {
ObjectInfo getObjectInfo();
}

@Embeddable
public class ObjectInfo {
@Column
private String objName;
@Column
private String objDocument;
...
}

@Entity
@SecondaryTable(name="COMMON",
pkJoinColumns=@PrimaryKeyJoinColumn(name="ID"))
public class Newsletter implements ObjectInfoProvider {
@Id
@GeneratedValue
@Column(name="IDREF")
private Long id;
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date newsletterDate;
@Column
private String newsletterHeader;
@Column
private String newsletterBody;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="objName", column=@Column(name="OBJNAME",
table="COMMON"))
,@AttributeOverride(name="objDocument",
column=@Column(name="OBJDOCUMENT", table="COMMON"))
})
private ObjectInfo objectInfo;
...
}

One good book with explanation for all inheritance related issues is this
one
http://www.amazon.de/Pro-EJB-Persistence-Experts-Voice/dp/15 90596455
and maybe this one too, but the focus of this book is the hibernate JPA
implementation
http://www.amazon.de/Java-Persistence-with-Hibernate/dp/1932 394885

Hope it helps,
Michael

"Kristian Rink" <kawazu@zimmer428.net> schrieb im Newsbeitrag
news:g7bo44$qd7$1@build.eclipse.org...
> Hi again;
>
> speaking of "tinsel" and obscure database design:
>
> Kristian Rink schrieb:
> [...]
>>> @Entity
>>> @DiscriminatorValue("NEWSLETTER")
>>> @Table(name="NEWSLETTER")
>>> @PrimaryKeyJoinColumn(name="IDREF")
>> [...]
>
> While this approach (@DiscriminatorColumn / @DiscriminatorValue) does
> rather
> well do in most situations (and, for that matters, makes migration of our
> DB
> abstraction a rather pleasant procedure), I now have stumbled across a set
> of situations in which this is not applicable, because, even though the
> hierarchy is right the same (extending classes, common base class,
> separate
> tables), there is no column usable as discriminator, leaving our backend
> system obviously doing a simple join across the two tables using the
> common
> ID, assuming the Discriminator is not required as "while the data is in
> the
> 'extending class' table, it per se must extend 'common' and thus have an
> entry there". Which leaves me dealing with this... simply dumping the
> @Discriminator* annotations, as supposed, broke my code again... Any way
> of
> doing an inheritance hierarchy here without @Discriminator*? And, asides
> that, any good books to be read on JPA dealing with these issues? Don't
> want
> to steal anyones time...
>
> Cheers & thanks for your patience,
> Kristian
>
> --
> Kristian Rink * http://zimmer428.net * http://flickr.com/photos/z428/ jab:
> kawazu@jabber.ccc.de * icq: 48874445 * fon: ++49 176 2447 2771 "One
> dreaming
> alone, it will be only a dream; many dreaming together is the beginning of
> a
> new reality." (Hundertwasser)
Previous Topic:Change tracking of many-to-many relationship broken?
Next Topic:DDL generation without database access
Goto Forum:
  


Current Time: Fri Apr 19 10:54:50 GMT 2024

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

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

Back to the top