首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Hibernate Session.save问题

问Hibernate Session.save问题
EN

Stack Overflow用户
提问于 2011-10-03 15:24:10
回答 3查看 1.4K关注 0票数 1

嗨,我有一个域对象,假设是Student和它的Roll no作为主键

下面是它的示例映射。

代码语言:javascript
复制
    @Id
@Column(name = "Roll_NO", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Roll_NO_SEQ")
@SequenceGenerator(name = "Roll_NO_SEQ", sequenceName = "Roll_NO_SEQ", allocationSize = 1)
public Long getRollNo() {
    return this.rollNo;
}

问题:假设某个学生从数据库中被删除,然后在重新录取时重新录取,我想保留旧的学号。因此,当我调用session.save时,hibernate会根据指定的顺序而不是我通过setRollNo()方法设置的内容分配一个新的roll。在hibernate中有什么方法可以做到这一点吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-04 07:49:38

考虑到您不能更改遗留代码,Ryan有一个正确的想法。不久前,在一个个人项目中,我基本上也做了同样的事情。有两个部分:简单的部分是允许有效地设置其他自动编号的列的ID...and,另一部分是当您转到Save()时使ID生成器停止覆盖该值。

下面是我使用的FlexibleIDGenerator的代码:

代码语言:javascript
复制
public class FlexibleIDGenerator extends IdentityGenerator implements Configurable {
   public static final String DEFAULT = "default";

   private IdentifierGenerator assignedGenerator;
   private IdentifierGenerator defaultGenerator;

@SuppressWarnings("unchecked")
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
      //boolean useDefault = false;

      if (object instanceof OverridableIdentity) {
          if (((OverridableIdentity) object).isIDOverridden()) {
              try {
                  Class cl = object.getClass().getSuperclass();
                  Method[] methods = cl.getDeclaredMethods();

                  for (int i = 0; i < methods.length; i++) {
                      if (methods[i].getName().equalsIgnoreCase("setId")) {
                          methods[i].invoke(object, Integer.valueOf((((OverridableIdentity) object).getOverriddenID())));
                      }
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
              return assignedGenerator.generate(session, object);
          } else {
              return defaultGenerator.generate(session, object);
          }
      } else {
          return defaultGenerator.generate(session, object);
      }
   }

   public void configure(Type type, Properties params, Dialect d) throws MappingException {
      assignedGenerator = IdentifierGeneratorFactory.create("assigned", type, params, d);
      defaultGenerator = IdentifierGeneratorFactory.create("increment", type, params, d);          
   }
}

要将其用于类,请按如下方式更新Hibernate映射文件:

代码语言:javascript
复制
        <id
        name="Id"
        type="integer"
        column="id"
    >
        <generator class="com.mypackage.FlexibleIDGenerator"/>
    </id>

另一个细节:我在基本对象中添加了一个名为"GetOverriddenID()“的方法,以避免混淆我使用的是”普通“ID (在Update()调用中)还是被覆盖的ID。

希望这能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2011-10-03 15:47:32

不要删除记录,添加一个名为soemthign的新布尔值字段,就像active或valid,而不是删除,只需使active = false即可。

或,

您可以将要删除的记录插入到存档表中,然后删除,然后从那里查找。

票数 3
EN

Stack Overflow用户

发布于 2011-10-04 07:22:55

考虑到您不能更改行的删除,另一种方法是编写您自己的id生成器,该生成器仅在尚未赋值的情况下获得新的序列值。有关编写自己的生成器的信息,请参阅section 5.1.2.2 in the reference guide的末尾。我以前从来没有尝试过,所以我只能给你指出大致的方向。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7632112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档