开发者

Hibernate Session.save issue

开发者 https://www.devze.com 2023-04-09 22:02 出处:网络
Hi I have a domain object lets say Student and its Roll no as a primary key here is the sample mapping for it.

Hi I have a domain object lets say Student and its Roll no as a primary key

here is the sample mapping for it.

    @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;
}

issue : lets say if a particular student was deleted from the database, and then re-admitted at the time of re-admission i want to retain the old roll no . so when i call session.save hibernate assigns a new roll No based on the Sequenc开发者_如何学运维e specified rather then what i am setting through setRollNo() method. is there any way to achieve this in hibernate?


don't delete the record, add a new boolean field called soemthign like active or valid, and instead of deleting just make active = false.

Or,

You could insert the record to be deleted into an archive table and then delete, and then look up from there.


Given that you cannot change the legacy code, Ryan has the right idea. I had to do basically the same thing some time ago in a personal project. There were two parts: the easy part is to allow the effective setting of an otherwise-autonumber-ed column's ID...and the other is to make the ID generator stop overwriting that value when you go to Save().

Here's the code to the FlexibleIDGenerator I used:

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);          
   }
}

To use that for a class, you update your Hibernate mapping file like this:

        <id
        name="Id"
        type="integer"
        column="id"
    >
        <generator class="com.mypackage.FlexibleIDGenerator"/>
    </id>

One other detail: I added a method to my base object called "GetOverriddenID()" to avoid confusion about whether I'm using the "normal" ID (in Update() calls) or the overridden ones.

Hope that helps.


Given that you can't change the deleting of the rows, another way would be to write your own id generator that will only get a new sequence value if a value isn't already assigned. See the end of section 5.1.2.2 in the reference guide for info about writing your own generator. I've never tried this before, so I can only point you in the general direction.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号