休眠 - 自动或手动ID - 在群集环境中

时间:2014-01-24 18:25:51

标签: java mysql hibernate identity

我遇到需要保存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范围排除应用程序)

请帮忙

由于

2 个答案:

答案 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();

    }
}
}