I have an issue about hibernate. As you can see I have a many to one relationship between EnvelopeEvent and EnvelopeProcess, the thing is I am not using ID to do the link, instead in table ENVELOPE_EVENT.ENVELOPE_FK it is pointing to ENVELOPE_PROCESS.ENVELOPE_ID, everything works perfect when I do insert. But when I try to select, EnvelopeProcess.events is always empty. I turned on the hibernate logs, and I notice it is using EnvelopeProcess.id as the key to lookup EnvelopeEvent, which is not what my purpose. I want it to use EnvelopeProcess.envelopeId to look for EnvelopeEvent. When I do debugging, I also notice org.hibernate.type.CollectionType.foreignKeyPropertyName is always null for my class EnvelopeProcess , which is also not what is supposed to be. My hibernate version is 5.4.27.Final
Here is my code:
public class EnvelopeProcess extends AbstractEntity{
private static final long serialVersionUID = 222222L;
private String envelopeId;
private String status;
private String subject;
private Set<EnvelopeEvent> events;
public Long getQuoteId() {
return quoteId;
}
public void setQuoteId(Long quoteId) {
this.quoteId = quoteId;
}
public String getEnvelopeId() {
return envelopeId;
}
public void setEnvelopeId(String envelopeId) {
this.envelopeId = envelopeId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public Set<EnvelopeEvent> getEvents() {
return events;
}
public void setEvents(Set<EnvelopeEvent> events) {
this.events = events;
}
//order by trigger time from latest to oldest
public List<EnvelopeEvent> getOrderedEvents(){
return this.events.stream()
.sorted((e1, e2) -> e2.getTriggerTime().compareTo(e1.getTriggerTime()))
.collect(Collectors.toList());
}
public EnvelopeEvent getLatestEvent() {
return this.getOrderedEvents().get(0);
}
}
<class name="com.pat.storage.entities.EnvelopeProcess" table="ENVELOPE_PROCESS" polymorphism="implicit" mutable="true" dynamic-insert="false" dynamic-update="false" >
<cache usage="read-write" region="com.pat.storage.entities"/>
<id name="id" type="long" unsaved-value="null" >
<column name="ID"/>
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="sequence_name">ZSEQID_ENVELOPE_PROCESS</param>
<param name="initial_value">1</param>
<param name="increment_size">10</param>
<param name="optimizer">pooled-lo</param>
<param name="value_column">next_value</param>
<param name="force_table_use">true</param>
</generator>
</id>
<version name="version" type="int" column="VERSION"/>
<property name="envelopeId" type="string" length="255">
<column name="ENVELOPE_ID" not-null="false" unique="false" />
</property>
<property name="status" type="string" length="255">
<column name="STATUS" not-null="false" unique="false" />
</property>
<property name="subject" type="string" length="255">
<column name="SUBJECT" not-null="false" unique="false" />
</property>
<set name="events" lazy="false" fetch="select" inverse="true" cascade="all">
<cache usage="read-write" region="com.pat.storage.collections"/>
<key foreign-key="ENVELOPE_EVENT_FKC" not-null="false" >
<column name="ENVELOPE_FK"/>
</key>
<one-to-many class="com.pat.storage.entities.EnvelopeEvent" not-found="exception"/>
</set>
</class>
public class EnvelopeEvent extends AbstractEntity{
private static final long serialVersionUID = -11111L;
private String eventType;
private Date triggerTime;
private EnvelopeProcess envelopeProcess;
public EnvelopeProcess getEnvelopeProcess() {
return envelopeProcess;
}
public void setEnvelopeProcess(EnvelopeProcess envelopeProcess) {
this.envelopeProcess = envelopeProcess;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public Date getTriggerTime() {
return triggerTime;
}
public void setTriggerTime(Date triggerTime) {
this.triggerTime = triggerTime;
}
}
<class name="com.iqx.storage.entities.EnvelopeEvent" table="ENVELOPE_EVENT" polymorphism="implicit" mutable="true" dynamic-insert="false" dynamic-update="false" >
<cache usage="read-write" region="com.iqx.storage.entities"/>
<id name="id" type="long" unsaved-value="null" >
<column name="ID"/>
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="sequence_name">ZSEQID_ENVELOPE_EVENT</param>
<param name="initial_value">1</param>
<param name="increment_size">10</param>
<param name="optimizer">pooled-lo</param>
<param name="value_column">next_value</param>
<param name="force_table_use">true</param>
</generator>
</id>
<version name="version" type="int" column="VERSION"/>
<property name="eventType" type="string" length="255">
<column name="EVENT_TYPE" not-null="true" unique="false" />
</property>
<property name="triggerTime" type="timestamp" precision="3">
<column name="TRIGGER_TIME" not-null="true" unique="false"/>
</property>
<many-to-one name="envelopeProcess" class="com.iqx.storage.entities.EnvelopeProcess" cascade="none"
foreign-key="ENVELOPE_EVENT_FKC" not-null="true" lazy="proxy" fetch="select" property-ref="envelopeId">
<column name="ENVELOPE_FK" not-null="false" />
</many-to-one>
</class>
Problem is solved, adding property-ref to the key tag of the collection is the solution.