我一直在寻找一种生成ID的方法,而不会在Hibernate中实际持久化实体。原因是我想手动插入新的数据库行。理想的情况是使用MySQL中存在的自动增量,但由于我使用的是InheritanceType.TABLE_PER_CLASS,这是不可能的。 (无法切换继承映射或序列生成的策略,因为该项目已经相当成熟。)
我所做研究的结论是(如果我错了,请纠正我):
我从结论中得出的结论:
这让我有了将ID生成过程委托给Hibernate的唯一选择,因为我不清楚如何生成ID。除了我不清楚的事实,我想有一个适用于不同ID生成策略的解决方案。
所以我想采取的方法是从java代码生成一堆id,然后为我“保留”(包含next_val的支持表得到更新),所以我可以在我的INSERT查询中使用它们。
这看起来像这样:
给出以下定义:
@Entity
@Table(name="datamodel")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class DataModel {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="model_sequence")
@SequenceGenerator(
name="model_sequence",
sequenceName="model_sequence",
allocationSize=20
)
@Column(name="id", nullable=false, unique=true, length=11)
private int id;
}
以这样的方式生成ID:
// This will be the ID generator, a
// long-lived object that generates ids
IDGenerator gen = new IDGenerator();
gen.initialize(DataModel.class, ... /* provide a serviceRegistry, sessionFactory, or anything else that might be needed to initialize this object */);
// This will generate the next ID based
// on the parameters passed to @SequenceGenerator
// and the values that are present in the DB.
int nextId = gen.generateNextId(/* provide a session, transaction, or anything else that might be needed for accessing the DB */);
以下帖子帮助我进一步了解:
我目前的尝试仍然停留在这一点上:
URL configUrl = this.getClass().getClassLoader().getResource("hibernate.main.cfg.xml");
Configuration configuration = new Configuration().configure(configUrl);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactorysessionFactory = configuration.buildSessionFactory(serviceRegistry);
Properties generatorProperties = new Properties();
// Properties would normally be read from annotations
// that are present on the entity class
generatorProperties.put("name", "model_sequence");
generatorProperties.put("sequence_name", "model_sequence");
generatorProperties.put("allocation_size", 20);
sequenceGenerator = new SequenceStyleGenerator();
sequenceGenerator.configure(LongType.INSTANCE, generatorProperties, serviceRegistry);
// Without the line below, the queries that Hibernate uses to read
// and alter the sequence table are not initialized (they are null)
// and Hibernate throws an exception
sequenceGenerator.registerExportables( database?? /* This requires a Database object, but how to provide it? */);
// In order to generate a new ID, do the following:
Session session = sessionFactory.getCurrentSession();
Serializable id = sequenceGenerator.generate((SessionImplementor)session, entity?? /* This requires an entity, but that is exactly what I'm trying to omit. */);
我对这种方法的考虑:
你们有没有想过如何做到这一点?