भले ही आपने GenerationType.AUTO
. का इस्तेमाल किया हो बिना किसी SEQUENCE विशिष्ट पैरामीटर के, आप असाइन किए गए पहचानकर्ताओं को सहेजने में सक्षम नहीं होंगे।
यदि आप कुछ समझौता करने के इच्छुक हैं तो कुछ समाधान हैं:
-
एक तरीका असाइन किए गए पहचानकर्ताओं पर स्विच करना होगा। आप यूयूआईडी पहचानकर्ताओं का उपयोग कर सकते हैं, जो MySQL और Oracle दोनों के लिए काम करते हैं और आप मैन्युअल रूप से मान भी निर्दिष्ट कर सकते हैं।
-
दूसरा तरीका कस्टम टेबल जनरेटर का उपयोग करना है।
सबसे पहले आप एक पहचान योग्य इंटरफ़ेस परिभाषित करें:
public interface Identifiable<T extends Serializable> {
T getId();
}
फिर आप टेबल जनरेटर का विस्तार करें:
public class AssignedTableGenerator extends TableGenerator {
@Override
public Serializable generate(SessionImplementor session, Object obj) {
if(obj instanceof Identifiable) {
Identifiable identifiable = (Identifiable) obj;
Serializable id = identifiable.getId();
if(id != null) {
return id;
}
}
return super.generate(session, obj);
}
}
यह जनरेटर असाइन किए गए पहचानकर्ताओं को सिंथेटिक जेनरेट किए गए पहचानकर्ताओं के साथ मिलाने में सक्षम है:
doInTransaction(session -> {
for (int i = 0; i < 5; i++) {
session.persist(new AssignTableSequenceIdentifier());
}
AssignTableSequenceIdentifier tableSequenceIdentifier = new AssignTableSequenceIdentifier();
tableSequenceIdentifier.id = -1L;
session.merge(tableSequenceIdentifier);
session.flush();
});
निम्नलिखित कथन उत्पन्न करना:
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
insert into sequence_table (sequence_name, next_val) values (default,1)
update sequence_table set next_val=2 where next_val=1 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=3 where next_val=2 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=4 where next_val=3 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=5 where next_val=4 and sequence_name=default
select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
update sequence_table set next_val=6 where next_val=5 and sequence_name=default
select identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1
insert into assigneTableIdentifier (id) values (1, 2)
insert into assigneTableIdentifier (id) values (2, 4)
insert into assigneTableIdentifier (id) values (5, -1)
Oracle के लिए, आप SEQUENCE और असाइन किए गए जनरेटर को जोड़ सकते हैं। संक्षेप में, निम्नलिखित जनरेटर पर विचार करें:
public class AssignedSequenceStyleGenerator
extends SequenceStyleGenerator {
@Override
public Serializable generate(SessionImplementor session,
Object obj) {
if(obj instanceof Identifiable) {
Identifiable identifiable = (Identifiable) obj;
Serializable id = identifiable.getId();
if(id != null) {
return id;
}
}
return super.generate(session, obj);
}
}
आप इसे अपनी संस्थाओं में निम्नानुसार मैप कर सकते हैं:
@Id
@GenericGenerator(
name = "assigned-sequence",
strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.AssignedSequenceStyleGenerator",
parameters = @org.hibernate.annotations.Parameter(
name = "sequence_name",
value = "post_sequence"
)
)
@GeneratedValue(
generator = "assigned-sequence",
strategy = GenerationType.SEQUENCE
)
private Long id;
सभी कोड GitHub पर उपलब्ध हैं और एक आकर्षण की तरह काम करते हैं।