I try to change some old sqlj (native sql insert directly into java files in a not editor way) into EJB Entity and JPA.
But I keep getting org.hibernate.AnnotationException: Column name SPROG_FORKORTELSE of to.ejb3.entity.geografi.RegionAktivMVItem not found in JoinColumns.referencedColumnName
If I remove the references between RegionAktivMVItem and ImageMapItem in the code below it deploys.
So I guess the problem is the RegionAktivMVItem has a composite key (Long RegionId, String Sprog) while ImageMapItem has a composite key (Long ImageMapId, Long RegionId).
RegionAktivMVItem represent the regions in Denmark where ImageMapItem is the different imagemap shapes on a map of Denmark.
Sprog means language.
ImageMapItem contains several sets of shapes (for different maps) identified with ImageMapId.
I want one ImageMapItem to join with all the different Sprog on RegionAktivMVItem as the shapes is the same for all languages.
Is it possible to do this in JPA/Hibernate? Purhaps through a Hibernate specific notation?
I use JBoss 4.2.3 with the bundled Hibernate.
I've inserted the original native SQL in the bottom for reference.
PS. The reason I don't just use createNativeQuery and the original native SQL is because of the inline cursor which I can't find a way map into a bean/collection. If anyone has a solution for this I could use this as well!
Code:
package to.ejb3.entity.geografi;
import to.ejb3.entity.sprog.Sprog;
import to.ejb3.entity.virksomhed.Virksomhed;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
@NamedQueries(
{
@NamedQuery(name = "regionAktivMV.findAllBySprogBrancheNavnImageMapId", query =
"select r from RegionAktivMVItem r " +
" left join fetch r.lokalOmraadeAktivMVItems "+
" left outer join r.imageMapItems imi " +
"where r.virksomhed.id = :pVirksomhedId " +
" and r.sprog = :pSprog "+
" and r.brancheNavn = :pBrancheNavn " +
" and imi.imageMapItemPK.imageMapId = :pImageMapId " +
"ORDER BY r.sortering, r.navn"
)
}
)
@Entity()
@Table(name = "region_aktiv_mv")
@IdClass(RegionAktivMVItemPK.class)
public class RegionAktivMVItem {
Long mRegionId;
String mSprog;
String mNavn;
Long mSortering;
String mBrancheNavn;
Virksomhed mVirksomhed;
String mBeskrivelse;
Collection<LokalOmraadeAktivMVItem> mLokalOmraadeAktivMVItems;
Collection<ImageMapItem> mImageMapItems;
@Id
@Column(name = "SPROG_FORKORTELSE")
public String getSprog() {
return mSprog;
}
public void setSprog(String pSprog) {
mSprog = pSprog;
}
@Id
@Column(name = "ID")
public Long getRegionId() {
return mRegionId;
}
public void setRegionId(Long pRegionId) {
mRegionId = pRegionId;
}
public String getNavn() {
return mNavn;
}
public void setNavn(String pNavn) {
mNavn = pNavn;
}
public Long getSortering() {
return mSortering;
}
public void setSortering(Long pSortering) {
mSortering = pSortering;
}
@Column(name = "BRANCHENAVN")
public String getBrancheNavn() {
return mBrancheNavn;
}
public void setBrancheNavn(String pBrancheNavn) {
mBrancheNavn = pBrancheNavn;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "VIRKSOMHED_ID")
public Virksomhed getVirksomhed() {
return mVirksomhed;
}
public void setVirksomhed(Virksomhed pVirksomhed) {
mVirksomhed = pVirksomhed;
}
@OneToMany(mappedBy = "regionAktivMVItem", fetch = FetchType.LAZY)
public Collection<LokalOmraadeAktivMVItem> getLokalOmraadeAktivMVItems()
{
return mLokalOmraadeAktivMVItems;
}
public void setLokalOmraadeAktivMVItems(Collection<LokalOmraadeAktivMVItem> pLokalOmraadeAktivMVItems) {
mLokalOmraadeAktivMVItems = pLokalOmraadeAktivMVItems;
}
public String getBeskrivelse() {
return mBeskrivelse;
}
public void setBeskrivelse(String pBeskrivelse) {
mBeskrivelse = pBeskrivelse;
}
@OneToMany(mappedBy = "regionAktivMVItem", fetch = FetchType.LAZY)
public Collection<ImageMapItem> getImageMapItems()
{
return mImageMapItems;
}
public void setImageMapItems(Collection<ImageMapItem> pImageMapItems) {
mImageMapItems = pImageMapItems;
}
}
Code:
package to.ejb3.entity.geografi;
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.persistence.Column;
import java.io.Serializable;
public class RegionAktivMVItemPK implements Serializable
{
Long mRegionId;
String mSprog;
public RegionAktivMVItemPK()
{
}
@Column(name = "ID" )
public Long getRegionId()
{
return mRegionId;
}
public void setRegionId(Long pRegionId)
{
mRegionId = pRegionId;
}
@Column(name = "SPROG_FORKORTELSE")
public String getSprog()
{
return mSprog;
}
public void setSprog(String pSprog)
{
mSprog = pSprog;
}
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final RegionAktivMVItemPK that = (RegionAktivMVItemPK) o;
if (mRegionId != null ? !mRegionId.equals(that.mRegionId) : that.mRegionId != null) {
return false;
}
if (mSprog != null ? !mSprog.equals(that.mSprog) : that.mSprog != null) {
return false;
}
return true;
}
public int hashCode()
{
int vresult;
vresult = (mRegionId != null ? mRegionId.hashCode() : 0);
vresult = 29 * vresult + (mSprog != null ? mSprog.hashCode() : 0);
return vresult;
}
}
Code:
package to.ejb3.entity.geografi;
import javax.persistence.*;
@Entity()
@Table(name = "IMAGEMAPITEM")
@IdClass(ImageMapItemPK.class)
public class ImageMapItem {
Long mImageMapId;
Long mRegionId;
private ImageMap mImageMap;
private RegionAktivMVItem mRegionAktivMVItem;
private String mCoords;
private String mShape;
@Id
@Column(name = "IMAGEMAP_ID" )
public Long getImageMapId()
{
return mImageMapId;
}
public void setImageMapId(Long pImageMapId)
{
mImageMapId = pImageMapId;
}
@Id
@Column(name = "REGION_ID")
public Long getRegionId()
{
return mRegionId;
}
public void setRegionId(Long pRegionId)
{
mRegionId = pRegionId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "IMAGEMAP_ID", insertable = false, updatable = false)
public ImageMap getImageMap() {
return mImageMap;
}
public void setImageMap(ImageMap pImageMap) {
mImageMap = pImageMap;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REGION_ID", referencedColumnName = "ID", unique = false, insertable = false, updatable = false)
public RegionAktivMVItem getRegionAktivMVItem() {
return mRegionAktivMVItem;
}
public void setRegionAktivMVItem(RegionAktivMVItem pRegionAktivMVItem) {
mRegionAktivMVItem = pRegionAktivMVItem;
}
public String getCoords() {
return mCoords;
}
public void setCoords(String pCoords) {
mCoords = pCoords;
}
public String getShape() {
return mShape;
}
public void setShape(String pShape) {
mShape = pShape;
}
}
Code:
package to.ejb3.entity.geografi;
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.persistence.Column;
import java.io.Serializable;
public class ImageMapItemPK implements Serializable
{
Long mImageMapId;
Long mRegionId;
public ImageMapItemPK()
{
}
@Column(name = "IMAGEMAP_ID" )
public Long getImageMapId()
{
return mImageMapId;
}
public void setImageMapId(Long pImageMapId)
{
mImageMapId = pImageMapId;
}
@Column(name = "REGION_ID")
public Long getRegionId()
{
return mRegionId;
}
public void setRegionId(Long pRegionId)
{
mRegionId = pRegionId;
}
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final ImageMapItemPK that = (ImageMapItemPK) o;
if (mImageMapId != null ? !mImageMapId.equals(that.mImageMapId) : that.mImageMapId != null) {
return false;
}
if (mRegionId != null ? !mRegionId.equals(that.mRegionId) : that.mRegionId != null) {
return false;
}
return true;
}
public int hashCode()
{
int vresult;
vresult = (mImageMapId != null ? mImageMapId.hashCode() : 0);
vresult = 29 * vresult + (mRegionId != null ? mRegionId.hashCode() : 0);
return vresult;
}
}
The original native SQL:
Code:
select id, navn, cursor (SELECT id, navn, sortering, onlineBookbare, beskrivelse
FROM lokalomraade_aktiv_mv
WHERE toregion_id = region_aktiv_mv.id
AND lokalomraade_aktiv_mv.sprog_forkortelse = :pSprog
AND brancheNavn = :pBrancheNavn
AND (virksomhed_id is null or virksomhed_id = :pVirksomhedId)
ORDER BY sortering,navn) lokalOmraader, imi.coords, imi.shape, beskrivelse
from region_aktiv_mv left outer join imageMapItem imi on (region_aktiv_mv.id = imi.region_id and imi.imageMap_id = :pImageMapId)
left outer join toregion_beskrivelse rb on (rb.sprog_forkortelse = region_aktiv_mv.sprog_forkortelse and rb.toregion_id = region_aktiv_mv.id)
where region_aktiv_mv.virksomhed_id = :pVirksomhedId
and region_aktiv_mv.sprog_forkortelse = :pSprog
and region_aktiv_mv.branchenavn = :pBrancheNavn
ORDER BY region_aktiv_mv.sortering, region_aktiv_mv.navn