【问题标题】:Hibernate - Auto or Manual ID - On cluster environment休眠 - 自动或手动 ID - 在集群环境中
【发布时间】:2014-02-15 20:46:19
【问题描述】:

我遇到需要保存休眠对象的情况,但我不确定是否会通过调用应用程序(使用范围内的特殊逻辑 -​​ 唯一)来分配 ID。

如果没有分配 ID,我需要休眠来生成一个高于应用程序输入的可能 ID 范围的 ID(我知道范围)。否则应该使用应用程序输入。

我正在研究 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范围排除应用程序)

请帮忙

谢谢

【问题讨论】:

    标签: java mysql hibernate identity


    【解决方案1】:

    在数据库中,将您的序列设置为以特定数字开头(从您提到的范围开始),然后使用类似这样的内容作为您的 ID 注释,这将确保休眠将使用序列中的下一个 ID,并且您赢了'不必担心集群/非集群环境问题:

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;
    

    【讨论】:

    • 谢谢,我的问题有两个 1- MySQL 不支持序列 2. 我的 DO 对象可以填充预定义的 ID(通过来自不同系统的 API 调用继续数据迁移和同步)大约一个月 - 这些调用带有源系统中的 id)。不带 ID 的普通 API 调用,系统应识别并适当分配 id
    【解决方案2】:

    我终于使用数据库中的表实现了这一点,如下所示

    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();
    
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 2013-05-29
      • 2019-11-03
      • 2020-04-04
      • 1970-01-01
      • 1970-01-01
      • 2011-04-05
      相关资源
      最近更新 更多