自动生成的域类ID,包含异常

时间:2013-08-09 15:00:20

标签: hibernate postgresql grails id-generation

方案: 使用默认的Postgres序列生成器创建并插入域类(使用自定义方言为每个表创建一个序列,但我认为这是无关紧要的)。现在,在某些情况下,我想选择自己的ID进行插入。

我想象两种基本方式:

  • 首选:只需在保存之前在域中设置ID。如果未设置,请使用生成的ID。我天真地试过这个,但它没有用,即实例插入了自动生成的id,即使在域实例中已经设置了另一个id。
  • 使用“generator:assigned”映射并确定默认ID(让DB决定)。怎么做到最好?

1 个答案:

答案 0 :(得分:1)

好的,最后我想出了这个(基本上是其他人在不同时间点提出的各种建议的组合)

package org.hibernate.id;

import java.io.Serializable;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.Type;

public class UseExistingOrGenerateTabelNameSequenceIdGenerator extends org.hibernate.id.enhanced.SequenceStyleGenerator {

/**
 * {@inheritDoc} If the instance to insert does contain an ID
 * we use that id instead of an auto generated one.
 */
@Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
    Serializable id = session.getEntityPersister(null, object).getClassMetadata().getIdentifier(object, session);
    return id != null ? id : super.generate(session, object);
}

/**
 * {@inheritDoc} If the parameters do not contain a
 * {@link SequenceStyleGenerator#SEQUENCE_PARAM} name, we assign one based on the
 * table name.
 */
@Override
public void configure(final Type type, final Properties params, final Dialect dialect) {
    if (params.getProperty(SEQUENCE_PARAM) == null  || params.getProperty(SEQUENCE_PARAM).length() == 0) {
        String tableName = params.getProperty(PersistentIdentifierGenerator.TABLE);
        if (tableName != null) {
            params.setProperty(SEQUENCE_PARAM, "seq_" + tableName);
        }
    }
    super.configure(type, params, dialect);
}

}

要在域类上专门使用它,您可以包含类似

的内容
static mapping = {
    id generator:'org.hibernate.id.UseExistingOrGenerateTabelNameSequenceIdGenerator', params:[optimizer:'pooled', increment_size:10]
}

进入域类定义,它还允许指定id池及其大小。 到目前为止似乎运行良好:))