我遇到需要保存hibernate对象的情况,但我不确定是否通过调用app(使用范围内的特殊逻辑 - 唯一)来分配ID。
如果未分配ID,我需要休眠以生成高于应用程序输入的可能ID范围的ID(我知道范围)。否则应该使用app输入。
我正在研究MySQL - 检查我是否可以自定义生成器,如下所示
public class MyDOIdGenerator extends IdentityGenerator{
@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
if ((((MyDO) obj).getId()) == null) {
Serializable id = super.generate(session, obj) ;
return id;
} else {
return ((MyDO) obj).getId();
}
}
}
但我的问题是,我不知道super.generate在集群环境中的表现如何。它会维护服务器之间的ID同步吗?如何指定要开始的号码? (因为我需要在使用hibernate生成它时使用id范围排除应用程序)
请帮忙
由于
答案 0 :(得分:0)
在DB中,将序列设置为以特定数字开头(您提到的范围的开头),然后使用类似这样的ID注释,它将确保hibernate将使用序列中的下一个ID并赢得不必担心集群/非集群环境问题:
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
答案 1 :(得分:0)
我最终使用数据库中的表格实现了这个,如下所示
package com.yahoo.mb.do;
import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.IdentityGenerator;
import com.yahoo.sm.ads.common.log.Logger;
public class MyDOGenerator extends IdentityGenerator{
private static final Class clazz = MethodHandles.lookup().lookupClass();
private static final Logger logger = Logger.getLogger(clazz);
private static String selectQuery = "SELECT nextval FROM identity_value WHERE name='MY_DO' FOR UPDATE";
private static String updateQuery = "UPDATE identity_value SET nextval=?, last_updated=? WHERE name='MY_DO'";
@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
if ((((MyDO) obj).getId()) == null) {
Connection connection = session.connection();
try {
PreparedStatement selectStatement = connection.prepareStatement(selectQuery);
PreparedStatement updateStatement = connection.prepareStatement(updateQuery);
logger.info(clazz, "generate", "Generating nextval");
ResultSet rs = selectStatement.executeQuery();
if (rs.next()) {
Long id = rs.getLong("nextval");
logger.info(clazz, "generate", "Generated nextval: " + id);
updateStatement.setLong(1, id+1);
updateStatement.setDate(2, new java.sql.Date(new java.util.Date().getTime()));
logger.info(clazz, "generate", "Updating nextval: " + id);
updateStatement.executeUpdate();
return id;
}
} catch (SQLException e) {
logger.error(clazz, "generate", "Error generating ID" + e);
throw new HibernateException("Unable to generate MyDO id value");
}
return null;
} else {
return ((MyDO) obj).getId();
}
}
}