猿问

在Hibernate中绕过GeneratedValue(合并数据不在db中?)

我的问题与[1]或[2]中描述的相同。我需要手动设置默认情况下自动生成的值(为什么?导入旧数据)。如[1]中所述,使用Hibernate entity = em.merge(entity)可以解决问题。


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


有任何想法吗?


肥皂起泡泡
浏览 678回答 3
3回答

回首忆惘然

它可以通过以下代码在我的项目中运行:@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());@Overridepublic 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生成器(基于Identity策略),如果未设置ID,则将生成委托给默认生成器。主要缺点是它使您无法将Hibernate用作JPA提供程序...但是它与我的MySQL项目完美配合

交互式爱情

另一个实现,方法更简单。这其中的工作原理与两个基于XML注释或基于配置:它依靠休眠元数据中获取价值为对象的ID。根据您的配置替换SequenceGenerator为IdentityGenerator(或任何其他生成器)。(创建装饰器而不是子类,将装饰的ID生成器作为参数传递给此生成器,作为练习留给读者)。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);    }}

HUX布斯

更新LaurentGrégoire对于休眠5.2的答案,因为它似乎有所更改。public class UseExistingIdOtherwiseGenerateUsingIdentity extends IdentityGenerator {    @Override    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {        Serializable id = session.getEntityPersister(null, object).getClassMetadata().getIdentifier(object, session);        return id != null ? id : super.generate(session, object);    }}并像这样使用它:(替换包名)@Id@GenericGenerator(name = "UseExistingIdOtherwiseGenerateUsingIdentity", strategy = "{package}.UseExistingIdOtherwiseGenerateUsingIdentity")@GeneratedValue(generator = "UseExistingIdOtherwiseGenerateUsingIdentity")@Column(unique = true, nullable = false)protected Integer id;
随时随地看视频慕课网APP
我要回答