Class with @IdClass gets lazy-loaded when "id" field accessed

Description

When I access the getter named getCountryIsoCode() of the following class (owning a CGLIB proxy that HB gave me), there is some lazy-loading activity that occurs. Of course, the field countryIsoCode is not tagged with @Id, but this is because of the @IdClass annotation, but I would expect the same "will-no-lazy-load-when-only-id-fields-are-accessed" regular behavior.

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.AttributeOverride;
import org.hibernate.annotations.CollectionOfElements;
import javax.persistence.JoinColumn;
import javax.persistence.Column;
import javax.persistence.AttributeOverrides;
import java.io.Serializable;
import java.util.List;
import javax.persistence.ManyToOne;
import com.magrit.bdom.types.multilingual.I18nDescriptionPdo;
import org.hibernate.annotations.FetchMode;
import com.dom.systemconfiguration.entity.SpokenLanguagePdo;
import javax.persistence.Version;
import org.hibernate.annotations.Fetch;
import javax.persistence.Table;
import javax.persistence.Id;
import com.dom.geography.entity.CountrySubdivisionPdo.PrimaryKey;
import javax.persistence.JoinTable;
import javax.persistence.Embedded;
import javax.persistence.OneToMany;
import javax.persistence.IdClass;
import javax.persistence.JoinColumns;
import org.hibernate.annotations.Filter;
import java.util.ArrayList;
import org.hibernate.annotations.BatchSize;

@Entity
@Table(name="PLGE_CTRSD")
@IdClass(com.dom.geography.entity.CountrySubdivisionPdo.PrimaryKey.class)
@BatchSize(size=20)
public class CountrySubdivisionPdo implements Serializable {

public static class PrimaryKey implements Serializable {

// COLUMN: CTRSD_CD
/**

  • The "ISO Code" value.
    */
    private String code;

// COLUMN: CTR_ISO_CD
/**

  • The "Country" value.
    */
    private String countryIsoCode;

// COLUMN: CTRSD_CD
/**

  • Gets the "ISO Code" value.
    */
    @Column(name="CTRSD_CD", nullable=false)
    public String getCode() {
    return this.code;
    }

// COLUMN: CTRSD_CD
/**

  • Sets the "ISO Code" value.
    */
    public void setCode(String code) {
    this.code = code;
    }

// COLUMN: CTR_ISO_CD
/**

  • Gets the "Country" value.
    */
    @Column(name="CTR_ISO_CD", nullable=false)
    public String getCountryIsoCode() {
    return this.countryIsoCode;
    }

// COLUMN: CTR_ISO_CD
/**

  • Sets the "Country" value.
    */
    public void setCountryIsoCode(String countryIsoCode) {
    this.countryIsoCode = countryIsoCode;
    }

public boolean equals(Object o) {
if (o instanceof PrimaryKey) {
PrimaryKey other = (PrimaryKey) o;
return (
true // This is just because of the generation algorithm
&&
(
(this.getCode() == null && other.getCode() == null) ||
(this.getCode() != null && other.getCode() != null &&
this.getCode().equals(other.getCode()))
)
&&
(
(this.getCountryIsoCode() == null && other.getCountryIsoCode() == null) ||
(this.getCountryIsoCode() != null && other.getCountryIsoCode() != null &&
this.getCountryIsoCode().equals(other.getCountryIsoCode()))
)
);
}
return false;
}

}

// FK: PLGE_CTRSDLNG_FK_PLGE_CTRSD (TO)
private List<SpokenLanguagePdo> spokenLanguages;

// FK: PLGE_CTRSDTMZ_FK_PLGE_CTRSD (TO)
private List<TimezonePdo> timezones;

// FK: PLGE_CTRSD_FK_PLGE_CTR (FROM) / COLUMN(S): CTR_ISO_CD
private CountryPdo country;

// COLUMN: CTRSD_CD
/**

  • The "ISO Code" value.
    */
    private String code;

// COLUMN: CTR_ISO_CD
/**

  • The "Country" value.
    */
    private String countryIsoCode;

// MultilingualDescription BOJ
private List<I18nDescriptionPdo> descriptions;

// TS COLUMN: CTRSD_TS
private Integer revisionNumber;

// FK: PLGE_CTRSDLNG_FK_PLGE_CTRSD (TO)
@OneToMany(targetEntity=SpokenLanguagePdo.class)
@JoinTable(name="PLGE_CTRSDLNG",
joinColumns={ @JoinColumn(name = "CTR_ISO_CD", referencedColumnName = "CTR_ISO_CD"), @JoinColumn(name = "CTRSD_CD", referencedColumnName = "CTRSD_CD") },
inverseJoinColumns={ @JoinColumn(name = "SPLNG_ISO_CD", referencedColumnName = "SPLNG_ISO_CD") }
)
@Fetch(FetchMode.SUBSELECT)
public List<SpokenLanguagePdo> getSpokenLanguages() {
return this.spokenLanguages;
}

// FK: PLGE_CTRSDLNG_FK_PLGE_CTRSD (TO)
public void setSpokenLanguages(List<SpokenLanguagePdo> spokenLanguages) {
this.spokenLanguages = spokenLanguages;
}

// FK: PLGE_CTRSDLNG_FK_PLGE_CTRSD (TO)
/**

  • Convenience method. This method is not thread safe.
    */
    public void addSpokenLanguage(SpokenLanguagePdo spokenLanguagePdo) {
    if (this.spokenLanguages == null) {
    this.spokenLanguages = new ArrayList<com.dom.systemconfiguration.entity.SpokenLanguagePdo>();
    }
    this.spokenLanguages.add(spokenLanguagePdo);
    }

// FK: PLGE_CTRSDTMZ_FK_PLGE_CTRSD (TO)
@OneToMany(targetEntity=TimezonePdo.class)
@JoinTable(name="PLGE_CTRSDTMZ",
joinColumns={ @JoinColumn(name = "CTR_ISO_CD", referencedColumnName = "CTR_ISO_CD"), @JoinColumn(name = "CTRSD_CD", referencedColumnName = "CTRSD_CD") },
inverseJoinColumns={ @JoinColumn(name = "TMZ_UID", referencedColumnName = "TMZ_UID") }
)
@Fetch(FetchMode.SUBSELECT)
public List<TimezonePdo> getTimezones() {
return this.timezones;
}

// FK: PLGE_CTRSDTMZ_FK_PLGE_CTRSD (TO)
public void setTimezones(List<TimezonePdo> timezones) {
this.timezones = timezones;
}

// FK: PLGE_CTRSDTMZ_FK_PLGE_CTRSD (TO)
/**

  • Convenience method. This method is not thread safe.
    */
    public void addTimezone(TimezonePdo timezonePdo) {
    if (this.timezones == null) {
    this.timezones = new ArrayList<com.dom.geography.entity.TimezonePdo>();
    }
    this.timezones.add(timezonePdo);
    }

// FK: PLGE_CTRSD_FK_PLGE_CTR (FROM) / COLUMN(S): CTR_ISO_CD
@ManyToOne(fetch=FetchType.LAZY, optional=false)
@JoinColumns({
@JoinColumn(name="CTR_ISO_CD", referencedColumnName="CTR_ISO_CD")
})
public CountryPdo getCountry() {
return this.country;
}

// FK: PLGE_CTRSD_FK_PLGE_CTR (FROM) / COLUMN(S): CTR_ISO_CD
public void setCountry(CountryPdo country) {
this.country = country;
}

// COLUMN: CTRSD_CD
/**

  • Gets the "ISO Code" value.
    */
    // columnDo.getDomain(): {<classgrinning face with big eyesomain>;id=ALPHANUMERICUPPER$;sqlDataTypeName=VARCHAR;desc=Alphabetic/Numeric - upper ([A9]*);length=null;scale=-1;typeDef=0}
    @Id
    public String getCode() {
    return this.code;
    }

// COLUMN: CTRSD_CD
/**

  • Sets the "ISO Code" value.
    */
    public void setCode(String code) {
    this.code = code;
    }

// COLUMN: CTR_ISO_CD
/**

  • Gets the "Country" value.
    */
    // columnDo.getDomain(): {<classgrinning face with big eyesomain>;id=ALPHABETICUPPER$;sqlDataTypeName=VARCHAR;desc=Alphabetic - upper ([A]*);length=null;scale=-1;typeDef=0}
    @Id
    public String getCountryIsoCode() {
    return this.countryIsoCode;
    }

// COLUMN: CTR_ISO_CD
/**

  • Sets the "Country" value.
    */
    public void setCountryIsoCode(String countryIsoCode) {
    this.countryIsoCode = countryIsoCode;
    }

// MultilingualDescription BOJ
@CollectionOfElements
@JoinTable(
name="PLGE_CTRSD1",
joinColumns= {
@JoinColumn(name="CTRSD_CD", referencedColumnName="CTRSD_CD"),
@JoinColumn(name="CTR_ISO_CD", referencedColumnName="CTR_ISO_CD")
}
)
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "element.languageCode", column=@Column(name="LNG_CD")),
@AttributeOverride(name = "element.description", column=@Column(name="CTRSD_DES")),
@AttributeOverride(name = "element.descriptionKey", column=@Column(name="CTRSD_DES_CLE"))
})
@Filter(name="GLOBAL_unilingualDescription", condition="LNG_CD = :languageCode")
@Fetch(FetchMode.SUBSELECT)
public List<I18nDescriptionPdo> getDescriptions() {
return this.descriptions;
}

// MultilingualDescription BOJ
public void setDescriptions(List<I18nDescriptionPdo> descriptions) {
this.descriptions = descriptions;
}

// MultilingualDescription BOJ
/**

  • Convenience method. This method is not thread safe.
    */
    public void addDescription(I18nDescriptionPdo i18nDescriptionPdo) {
    if (this.descriptions == null) {
    this.descriptions = new ArrayList<com.magrit.bdom.types.multilingual.I18nDescriptionPdo>();
    }
    this.descriptions.add(i18nDescriptionPdo);
    }

// TS COLUMN: CTRSD_TS
@Version
@Column(name="CTRSD_TS", nullable=false)
public Integer getRevisionNumber() {
return this.revisionNumber;
}

// TS COLUMN: CTRSD_TS
public void setRevisionNumber(Integer revisionNumber) {
this.revisionNumber = revisionNumber;
}

}

Attachments

3
  • 10 Mar 2008, 06:16 PM
  • 10 Mar 2008, 06:16 PM
  • 10 Mar 2008, 06:15 PM

Activity

Steve EbersoleMarch 21, 2011 at 7:04 PM

Bulk closing stale resolved issues

Carl AllainMarch 10, 2008 at 7:29 PM

However, https://hibernate.atlassian.net/browse/HHH-3171#icft=HHH-3171 has the right priority since this bug affects the overall application performance since extra selects are made all the time.

Carl AllainFebruary 6, 2008 at 9:46 PM

I would say this sould be part of the support of the IdClass annotation

Carl AllainFebruary 6, 2008 at 9:21 PM

To reproduce, use a class with @IdClass primary key and try to access one of its Id fields agains a proxy you obtained with load()

Duplicate

Details

Assignee

Reporter

Components

Affects versions

Priority

Created January 15, 2008 at 10:20 PM
Updated March 21, 2011 at 7:04 PM
Resolved April 1, 2008 at 4:37 AM

Flag notifications