即使您使用时
GenerationType.AUTO没有任何SEQUENCE特定参数,也将无法保存分配的标识符。
如果您愿意做出一些妥协,则有一些解决方法:
一种方法是切换到分配的标识符。您可以使用适用于MySQL和Oracle的UUID标识符,也可以手动分配值。
另一种方法是使用自定义表生成器。
首先,您定义一个可识别的接口:
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 updateinsert into sequence_table (sequence_name, next_val) values (default,1)update sequence_table set next_val=2 where next_val=1 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=3 where next_val=2 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=4 where next_val=3 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=5 where next_val=4 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=6 where next_val=5 and sequence_name=defaultselect identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1insert 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上使用,并且像一个超级按钮一样工作。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)