NamedNativeQuery and Inheritance
aneh Aug 19, 2012 9:54 PMI have an inheritance heirarchy as below, a named native query and of course a problem. Excuse the strange formatting.
JpaRegistee
-- JpaOfferingRegistee
---- JpaFacilityRegistee
---- JpaProviderRegistee
The problem is centred around the discriminator column. I had originally assumed that this was the actual column in the database identified in the following code as "otype".
When I use this column as the discriminator in the SqlResultSetMapping I get an exception saying that getInt() has returned an invalid result. I do not see where or how this getInt()
is being called so this led me to the following.
I also inspected other generated code and found that instead of the actual database discrimintator column there was a common portion of sql generated such as:
+" | ,case | when facree.oid is not null then 2 " | ||||||||
+" | when proree.oid is not null then 1 " | |||||||||
+" | when offree.oid is not null then 0 " | |||||||||
+" | end as oty " |
I surmised that this integer column was then used to identify the position of the EntityResult in the sql result set mapping however when I use this as the
discrimintor column I get the following.an exception saying that column facility_12_0_ is not found. This column is not part of my
sql code and I assume is generated behind the scenes via the EntityManager processing the native query. I have the output sql option turned on but this generated content
is not displayed so I cannot see where or why this column of being referenced.
I have found very little by way of example or explaination (other than the most trivial cases) so I am at a loss as to the next possible steps? Can anyone point me in the
right direction to gather more information or perhaps the glaringly obvious mistake that I have made?
Here is the root class
@Entity | (name="RegistryRegistee") | ||||
@Table | (name="registry_registee", schema="istana") | ||||
@Inheritance | (strategy=InheritanceType.JOINED) | ||||
@DiscriminatorColumn | (name="otype", discriminatorType=DiscriminatorType.STRING,length=256) |
abstract
public class JpaRegistee
implements Registee, Serializable |
{
static | final | ||||||
private | long | serialVersionUID | = 1L; |
@Column | (name="oid") | ||||||
@Id | |||||||
private | String | m_oid; |
@ManyToOne | (targetEntity=JpaKalendar.class) | |||||
@JoinColumn | (name="kalendar_kalendar_oid") | |||||
private | Kalendar | m_kalendar; | ||||
@ManyToOne | (targetEntity=JpaRegistry.class) | |||||
@JoinColumn | (name="registry_registry_oid") | |||||
private | Registry | m_registry; | ||||
/* (non-Javadoc) | ||||||
* @see com.istana.registry.fixture.Registee#getKalendar() | ||||||
*/ | ||||||
@Override | ||||||
public | Kalendar | getKalendar() | ||||
{ | ||||||
return m_kalendar; | ||||||
} |
/* (non-Javadoc) | ||||||
* @see com.istana.registry.fixture.Registee#getRegistry() | ||||||
*/ | ||||||
@Override | ||||||
public | Registry | getRegistry() | ||||
{ | ||||||
return m_registry; | ||||||
} |
/* (non-Javadoc) | |||||||
* @see com.istana.registry.fixture.Registee#getOid() | |||||||
*/ | |||||||
@Override | |||||||
public | String | getOid() | |||||
{ | |||||||
return m_oid; | |||||||
} |
}
@Entity | (name="RegistryOfferingRegistee") | |||
@Table | (name="registry_offering_registee", schema="Istana") |
/*
* Not sure what will happen with associations so I will assume they are loaded through magic and simply load
* the explicit scalar properties of the classes.
*/
@SqlResultSetMapping(name="SqlRegisteeSearchA"
,entities= | {@EntityResult | (entityClass=JpaOfferingRegistee.class | ||||||||||||||||
,discriminatorColumn="oty" | ||||||||||||||||||
,fields | = | {@FieldResult(name="m_oid", | column = "oid") | |||||||||||||||
,@FieldResult(name="m_kalendar", | column = "kalendar_oid") | |||||||||||||||||
,@FieldResult(name="m_registry", | column = "registry_oid") | |||||||||||||||||
} | ||||||||||||||||||
) | ||||||||||||||||||
,@EntityResult | (entityClass=JpaProviderRegistee.class | |||||||||||||||||
,discriminatorColumn="oty" | ||||||||||||||||||
,fields | = | {@FieldResult(name="m_oid", | column = "oid") | |||||||||||||||
,@FieldResult(name="m_kalendar", | column = "kalendar_oid") | |||||||||||||||||
,@FieldResult(name="m_registry", | column = "registry_oid") | |||||||||||||||||
,@FieldResult(name="m_facilityRegistee", | column = "facility_registee_oid") | |||||||||||||||||
,@FieldResult(name="m_provider", | column = "provider_oid") | |||||||||||||||||
} | ||||||||||||||||||
) | ||||||||||||||||||
,@EntityResult | (entityClass=JpaFacilityRegistee.class | |||||||||||||||||
,discriminatorColumn="oty" | ||||||||||||||||||
,fields | = | {@FieldResult(name="m_oid", | column = "oid") | |||||||||||||||
,@FieldResult(name="m_kalendar", | column = "kalendar_oid") | |||||||||||||||||
,@FieldResult(name="m_registry", | column = "registry_oid") | |||||||||||||||||
,@FieldResult(name="m_facility", | column = "facility_oid") | |||||||||||||||||
,@FieldResult(name="m_carrying", | column = "carrying_oid") | |||||||||||||||||
} | ||||||||||||||||||
) | ||||||||||||||||||
} | ||||||||||||||||||
,columns= | {@ColumnResult(name = "oid") | |||||||||||||||||
,@ColumnResult(name = "oty") | ||||||||||||||||||
,@ColumnResult(name = "registry_oid") | ||||||||||||||||||
,@ColumnResult(name = "kalendar_oid") | ||||||||||||||||||
,@ColumnResult(name = "facility_oid") | ||||||||||||||||||
,@ColumnResult(name = "carrying_oid") | ||||||||||||||||||
,@ColumnResult(name = "provider_oid") | ||||||||||||||||||
,@ColumnResult(name = "facility_registee_oid") | ||||||||||||||||||
} | ||||||||||||||||||
) |
@NamedNativeQuery | (name="RegisteeSearchA" | |||||||||
,resultSetMapping="SqlRegisteeSearchA" | ||||||||||
,query= | ||||||||||
"select ree.oid as oid " | ||||||||||
+" | ,ree.otype as otyc " | |||||||||
+" | ,case | when facree.oid is not null then 2 " | ||||||||
+" | when proree.oid is not null then 1 " | |||||||||
+" | when offree.oid is not null then 0 " | |||||||||
+" | end as oty " | |||||||||
+" | ,ree.registry_registry_oid registry_oid " | |||||||||
+" | ,ree.kalendar_kalendar_oid kalendar_oid " | |||||||||
+" | ,facree.facility_facility_oid facility_oid " | |||||||||
+" | ,facree.facility_carrying_oid carrying_oid " | |||||||||
+" | ,proree.facility_registee_oid facility_registee_oid " | |||||||||
+" | ,proree.commerce_provider_oid provider_oid " | |||||||||
+" from istana.registry_registee ree " | ||||||||||
+" | inner join istana.registry_offering_registee offree on ree.oid=offree.oid " | |||||||||
/* | ||||||||||
* walk the offering facility path | ||||||||||
*/ | ||||||||||
+" | left outer join istana.registry_offering_facility_registee facree on ree.oid=facree.oid " | |||||||||
+" | left outer join istana.facility_facility facfac on facree.facility_facility_oid = facfac.oid " | |||||||||
+" | left outer join istana.facility_facility_locality facloc on facfac.oid = facloc.facility_facility_oid " | |||||||||
+" | left outer join istana.locality_geo_postal_au_postal faclocloc on facloc.locality_locality_oid = faclocloc.oid " | |||||||||
+" | left outer join istana.locality_geo_postal_au_post_code faclocpos on faclocloc.post_code_au = faclocpos.post_code_au " | |||||||||
/* | ||||||||||
* walk the offering provider path | ||||||||||
*/ | ||||||||||
+" | left outer join istana.registry_offering_provider_registee proree on ree.oid=proree.oid " | |||||||||
+" | left outer join istana.registry_offering_facility_registee profacree on proree.facility_registee_oid=profacree.oid " | |||||||||
+" | left outer join istana.facility_facility profac on profacree.facility_facility_oid = profac.oid " | |||||||||
+" | left outer join istana.facility_facility_locality proloc on profac.oid = proloc.facility_facility_oid " | |||||||||
+" | left outer join istana.locality_geo_postal_au_postal prolocloc on proloc.locality_locality_oid = prolocloc.oid " | |||||||||
+" | left outer join istana.locality_geo_postal_au_post_code prolocpos on prolocloc.post_code_au = prolocpos.post_code_au " | |||||||||
+"where | (faclocpos.post_code_au is not null and haversine(:fromLat,:fromLng,faclocpos.latitude,faclocpos.longitude) <= :distance) " | |||||||||
+" | or | (prolocpos.post_code_au is not null and haversine(:fromLat,:fromLng,prolocpos.latitude,prolocpos.longitude) <= :distance) " | ||||||||
) |
abstract
public class JpaOfferingRegistee extends JpaRegistee
implements OfferingRegistee |
{
static | final | ||||||
private | long | serialVersionUID | = 1L; |
}
The first descendent class
@Entity | (name="FacilityRegistee") | |||
@Table | (name="registry_offering_facility_registee", schema="Istana") | |||
@DiscriminatorValue | ("com.istana.registry.offering.fixture.jpa.JpaFacilityRegistee") |
public class JpaFacilityRegistee extends JpaOfferingRegistee
implements FacilityRegistee |
{
static | final | |||||||
private | long | serialVersionUID | = 1L; |
@ManyToOne | (targetEntity=JpaCarrying.class) | ||||||
@JoinColumn | (name="facility_carrying_oid") | ||||||
private | Carrying | m_carrying; | |||||
@ManyToOne | (targetEntity=JpaFacility.class) | ||||||
@JoinColumn | (name="facility_facility_oid") | ||||||
private | Facility | m_facility; | |||||
@OneToMany | (targetEntity=JpaProviderRegistee.class,mappedBy="m_facilityRegistee") | ||||||
private | Set<ProviderRegistee> | m_providerRegistees; | |||||
/* (non-Javadoc) | |||||||
* @see com.istana.registry.offering.fixture.FacilityRegistee#getFacility() | |||||||
*/ | |||||||
@Override | |||||||
public | Facility | getFacility() | |||||
{ | |||||||
return m_facility; | |||||||
} |
/* (non-Javadoc) | |||||||
* @see com.istana.registry.offering.fixture.FacilityRegistee#getCarrying() | |||||||
*/ | |||||||
@Override | |||||||
public | Carrying | getCarrying() | |||||
{ | |||||||
return m_carrying; | |||||||
} |
/* (non-Javadoc) | ||||||||
* @see com.istana.registry.fixture.Registee#getName() | ||||||||
*/ | ||||||||
@Override | ||||||||
public | String | getName() | ||||||
{ | ||||||||
return getFacility().getName(); | ||||||||
} |
/* (non-Javadoc) | ||||
* @see com.istana.registry.offering.fixture.FacilityRegistee#getProviderRegistees() | ||||
*/ | ||||
@Override | ||||
public | Set<ProviderRegistee> | getProviderRegistees() | ||
{ | ||||
return m_providerRegistees; | ||||
} |
/* (non-Javadoc) | |||||||
* @see com.istana.registry.offering.fixture.OfferingRegistee#getPolarCoord() | |||||||
*/ | |||||||
@Override | |||||||
public | PolarCoord | getPolarCoord() | |||||
{ | |||||||
/* | |||||||
* This needs more work to use a context to select the appropriate locality not just the first. | |||||||
*/ | |||||||
for (Locality l : getFacility().getLocalitys()) | |||||||
{ | |||||||
if | (l instanceof GeoLocality) | ||||||
{ | |||||||
return ((GeoLocality)l).getPolarCoord(); | |||||||
} | |||||||
} |
return null; | ||
} |
}
The second descendent
@Entity | (name="RegistryOfferingProviderRegistee") | |||
@Table | (name="registry_offering_provider_registee", schema="Istana") | |||
@DiscriminatorValue | ("com.istana.registry.offering.fixture.jpa.JpaProviderRegistee") |
public class JpaProviderRegistee extends JpaOfferingRegistee
implements ProviderRegistee |
{
static | final | ||||||
private | long | serialVersionUID | = 1L; |
@ManyToOne | (targetEntity=JpaFacilityRegistee.class) | |||||
@JoinColumn | (name="facility_registee_oid") | |||||
private | FacilityRegistee | m_facilityRegistee; | ||||
@ManyToOne | (targetEntity=JpaProvider.class) | |||||
@JoinColumn | (name="commerce_provider_oid") | |||||
private | Provider | m_provider; | ||||
/* (non-Javadoc) | ||||||
* @see com.istana.registry.offering.fixture.ProviderRegistee#getFacilityRegistee() | ||||||
*/ | ||||||
@Override | ||||||
public | FacilityRegistee | getFacilityRegistee() | ||||
{ | ||||||
return m_facilityRegistee; | ||||||
} |
/* (non-Javadoc) | |||||||
* @see com.istana.registry.fixture.Registee#getName() | |||||||
*/ | |||||||
@Override | |||||||
public | String | getName() | |||||
{ | |||||||
return getProvider().getParty().getName(); | |||||||
} |
/* (non-Javadoc) | ||||||
* @see com.istana.registry.offering.fixture.ProviderRegistee#getProvider() | ||||||
*/ | ||||||
@Override | ||||||
public | Provider | getProvider() | ||||
{ | ||||||
return m_provider; | ||||||
} |
/* (non-Javadoc) | ||||||
* @see com.istana.registry.offering.fixture.OfferingRegistee#getPolarCoord() | ||||||
*/ | ||||||
@Override | ||||||
public | PolarCoord | getPolarCoord() | ||||
{ | ||||||
return getFacilityRegistee().getPolarCoord(); | ||||||
} |
}