为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

肥皂起泡泡 2019-09-24 16:19:08
我的问题与[1]或[2]中描述的相同。我需要手动设置默认情况下自动生成的值(为什么?导入旧数据)。如[1]中所述,使用Hibernate entity = em.merge(entity)可以解决问题。对我来说不幸的是事实并非如此。我既没有收到错误,也没有其他任何警告。该实体只是不会出现在数据库中。我正在使用Spring和Hibernate EntityManager 3.5.3-Final。有任何想法吗?
查看完整描述

3 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

它可以通过以下代码在我的项目中运行:


@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生成器(基于Identity策略),如果未设置ID,则将生成委托给默认生成器。


主要缺点是它使您无法将Hibernate用作JPA提供程序...但是它与我的MySQL项目完美配合


查看完整回答
反对 回复 2019-09-24
?
交互式爱情

TA贡献1712条经验 获得超3个赞

另一个实现,方法更简单。


这其中的工作原理与两个基于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);

    }

}


查看完整回答
反对 回复 2019-09-24
?
HUX布斯

TA贡献1876条经验 获得超6个赞

更新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;


查看完整回答
反对 回复 2019-09-24
  • 3 回答
  • 0 关注
  • 677 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信