Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Absence of @DiscriminatorColumn causes exception: Unknown column DTYPE
Absence of @DiscriminatorColumn causes exception: Unknown column DTYPE [message #809483] Tue, 28 February 2012 18:22 Go to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Hello,

I have the following design:

index.php/fa/7347/0/

As you can see, there's a common base table SecurityIdentities for Users and Groups, which are currently mapped via JOINED inheritance *without using a discriminator*.

Here are the mappings:

@Entity
@Table(name = "SecurityIdentities")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class SecurityIdentity implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column
    protected Integer id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "identity_type_name", referencedColumnName = "name")
    protected IdentityType identityType;

    ...
}

Now on some EL expression (doesn't matter) the following SQL query is generated to join Users and SecurityIdentities (which causes a runtime exception BTW):

SELECT
 t0.ID,
 t0.DTYPE,              -- UGH!?
 t0.identity_type_name,
 t1.ID,
 t1.is_enabled,
 t1.NAME,
 t1.PASSWORD,
 t1.person_id
FROM
 SecurityIdentities t0,
 Users t1
WHERE ((t1.ID = t0.ID) AND (t0.DTYPE = ?))

I thought a @DiscriminatorColumn on an inheritance root class is only *optional* for JOINED inheritance. At least Hibernate doesn't need it. (???)

I then found:
http://stackoverflow.com/questions/2063515/why-eclipselink-is-adding-discriminator-column-for-joined-inheritance-strategy

Does EclipseLink really need a discriminator column for JOINED strategy? If so, could it be considered an enhancement to relax the requirement of a discriminator column in a JOINED inheritance? After all, the discriminator column isn't absolutely necessary as entities belonging together could be determined based on the FK columns/values only.

The policy for the code generator could go something like this:
If JOINED inheritance and @DiscriminatorColumn found, use it to join entities and generate the discriminator (as above), otherwise join via FKs and don't generate the DTYPE column in the SQL.

Opinions/comments welcome, especially from the EclipseLink team.

Thanks
Karsten
Re: Absence of @DiscriminatorColumn causes exception: Unknown column DTYPE [message #810805 is a reply to message #809483] Thu, 01 March 2012 10:29 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

EclipseLink assumes a DiscriminatorColumn is used by default, if one is not set, one is defaulted, as required by the JPA spec.

You can avoid requiring a DiscriminatorColumn by using a @ClassExtractor. The ClassExtractor will need to determine the class for the row (such as checking for the existence of a joined table). Using a DiscriminatorColumn is recommended and the best way to define inheritance.

Please log a bug that a special ClassExtractor or annotation should be provided to allow no discriminator to be used with joined inheritance. (maybe @JoinedDiscriminator). We cannot simply not use a DiscriminatorColumn if none is set because of backward compatibility, spec compliance, and because it is not the best solution to JOINED inheritance.

One reason EclipseLink uses a DiscriminatorColumn with JOINED inheritance, is that EclipseLink does not require an inheritance hierarchy be all JOINED. It is very common to have some subclass not add significant fields to justify a separate table for every subclass. Once you have any of the subclasses sharing a table, you need a discriminator, so always using one is the best solution.




James : Wiki : Book : Blog : Twitter
Re: Absence of @DiscriminatorColumn causes exception: Unknown column DTYPE [message #811173 is a reply to message #810805] Thu, 01 March 2012 21:15 Go to previous message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
James Sutherland wrote on Thu, 01 March 2012 10:29
... We cannot simply not use a DiscriminatorColumn if none is set because of backward compatibility, spec compliance, and because it is not the best solution to JOINED inheritance.

Hmm about spec compliance, I'm not so sure. The JPA 2 spec from 11/10/09 says:

Quote:
11.1.10 DiscriminatorColumn Annotation

For the SINGLE_TABLE mapping strategy, and typically also for the JOINED strategy, the persistence provider will use a type discriminator column. The DiscriminatorColumn annotation is used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies.

The strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied.[90]

The DiscriminatorColumn annotation can be specified on an entity class (including on an abstract entity class).

If the DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to "DTYPE" and the discriminator type to STRING.

To me the last sentence only says to generate the missing DTYPE column if the discriminator is required. The question is: is a discriminator ultimately required for JOINED inheritance? I have doubts here and it seems it was rather interpreted that way to ease the implementation of EclipseLink.

Final note: In any case, this forces modeling a database column because some technology higher in the stack requires it.

Karsten

[Updated on: Fri, 02 March 2012 04:36]

Report message to a moderator

Previous Topic:Find after persist - ignoring cache
Next Topic:QueuableWeakCacheKey growing endlessly
Goto Forum:
  


Current Time: Tue Sep 02 05:09:58 EDT 2014

Powered by FUDForum. Page generated in 0.02129 seconds