绕过休眠中生成的值(合并数据不在 db 中?

2022-08-31 23:46:23

我的问题与 [1] 或 [2] 中描述的相同。我需要手动设置默认自动生成的值(为什么?导入旧数据)。如 [1] 中所述,使用 Hibernate's 将做到这一点。entity = em.merge(entity)

不幸的是,对我来说它没有。我既没有得到错误,也没有收到任何其他警告。实体不会出现在数据库中。我正在使用Spring和Hibernate EntityManager 3.5.3-Final。

有什么想法吗?


答案 1

另一种实现,更简单。

这个适用于基于注释或基于xml的配置:它依赖于休眠元数据来获取对象的id值。替换为(或任何其他发生器),具体取决于您的配置。(创建装饰器而不是子类化,将修饰的ID生成器作为参数传递给此生成器,留给读者作为练习)。SequenceGeneratorIdentityGenerator

public class UseExistingOrGenerateIdGenerator extends SequenceGenerator {
    @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);
    }
}

练习的答案(根据要求使用装饰器模式),未真正测试:

public class UseExistingOrGenerateIdGenerator implements IdentifierGenerator, Configurable {

    private IdentifierGenerator defaultGenerator;

    @Override
    public void configure(Type type, Properties params, Dialect d) 
                        throws MappingException;
        // For example: take a class name and create an instance
        this.defaultGenerator = buildGeneratorFromParams(
                params.getProperty("default"));
    }

    @Override
    public Serializable generate(SessionImplementor session, Object object)
                        throws HibernateException {
        Serializable id = session.getEntityPersister(null, object)
                      .getClassMetadata().getIdentifier(object, session);
        return id != null ? id : defaultGenerator.generate(session, object);
    }
}

答案 2

它使用以下代码在我的项目上工作:

@XmlAttribute
@Id
@Basic(optional = false)
@GeneratedValue(strategy=GenerationType.IDENTITY, generator="IdOrGenerated")
@GenericGenerator(name="IdOrGenerated",
                  strategy="....UseIdOrGenerate"
)
@Column(name = "ID", nullable = false)
private Integer id;

import org.hibernate.id.IdentityGenerator;
...
public class UseIdOrGenerate extends IdentityGenerator {
private static final Logger log = Logger.getLogger(UseIdOrGenerate.class.getName());

@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
    if (obj == null) throw new HibernateException(new NullPointerException()) ;

    if ((((EntityWithId) obj).getId()) == null) {
        Serializable id = super.generate(session, obj) ;
        return id;
    } else {
        return ((EntityWithId) obj).getId();

    }
}

在这里,您基本上定义了自己的ID生成器(基于标识策略),如果未设置ID,则将生成委托给默认生成器。

主要缺点是它将您绑定到Hibernate作为JPA提供程序...但它与我的MySQL项目完美配合


推荐