2

I have a legacy MS SQL Server 2000 datatabase I am trying to map with JPA (EclipseLink to be precise).

I have a table "CONTACT1" with a text field "KEY1" which can be either 'Contact' or 'Asset', and I am using:

@Table(name = "CONTACT1")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "KEY1")
public abstract class Record {

to map it to two different classes (Contact and Asset).

@Entity
@DiscriminatorValue(value = "Contact")
public class Contact extends Record {...}

and

@Entity
@DiscriminatorValue(value = "Asset")
public class Asset extends Record {...}

Unfortunately I found out some or the records are missing, and after further analysis I realised some contact records have the "KEY1" field set to NULL.

While I could just run an update query to fix the problem I would like to avoid that - is there a way to map that 'NULL' value to a Contact class?

Failing that, is there a mechanism in JPA where I can pre-filter the recordsets making JPA believe that field is not NULL but it has 'Contact' written in it?

thedayofcondor
  • 3,860
  • 1
  • 19
  • 28

2 Answers2

0

You need to run the update and assign correct values to the rows with null values in the database. I also advice you to modify the column definition in the database and set a default value for it, to prevent null in the future.

Or don't use @DiscriminatorColumn. In my experience, it tends to add more complexity and bugs than it's worth.

pap
  • 27,064
  • 6
  • 41
  • 46
  • Unfortunately,as I said, it is a legacy database and I have close to no control over it, I access it readonly. Doing that update would mean an endless cycle of re-testing. But I would like to know more about your experience with @DiscriminatorColumn - what would you recommend instead? – thedayofcondor Nov 08 '12 at 14:29
  • I recommend using as clean entities as possible, that map one-to-one to a table. This holds especially true in when you are restricted to an existing, inflexible data model. `@Inheritance` doesn't really deliver anything you can't achieve using simple entities and properties. Attempting to shoe-horn a relational data structure into something that it isn't (a polymorphic inheritance structure) is something I've never been keen on. – pap Nov 08 '12 at 15:21
  • I fully agree - but you should see this database... it has a field to hold a string, and another field in the same table to hold the uppercase version of the same string. With the exception of the primary key, all the other fields have to be "interpreted", eg a field is the phone number if it is a 'Contact' or the serial number if it is an 'Asset'. Using table inheritance allows me to handle these two cases properly - but there must be a misconfigured client on the network setting NULLs - so even if I update the table I am afraid NULLs will start happening again – thedayofcondor Nov 08 '12 at 16:05
0

Just a clarification : I found that if you set a @DiscriminatorColumn annotation on any column (e.g.KEY1 here), Hibernate ORM creates a database schema with a NOT NULL constraint. Since your legacy DB has null values maybe an ALTER table to make it NULLABLE has been issued later. Details in : https://hibernate.atlassian.net/browse/HHH-12445

Solution 1: You can using Discriminator formula to map the null values to the preferred entity class.

@DiscriminatorFormula("case when key1 is null then 'Contact' else key1 end)
@DiscriminatorValue(value = "Contact")

Note Example 247 in https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html

Solution:2 You can also use @DiscriminatorColumn("null") to map that row to "Contact" entity class. Example 254 in https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#entity-inheritance-discriminator-implicit

BigHeadNelson
  • 73
  • 1
  • 4