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(); | ||||||
| } |
}