Howard Jus
Howard Jus

Reputation: 1

How to persist a JPA autogenerated value before commit?

Hi I am beginner on the JPA world, I have a question on the auto-generated id. We are using OpenJPA, My application requires that one operation which creates bunch of related objects must be inside a single transaction which will be part of global transaction (XA). I am struggling in get the auto-generated id and use it to set values in other object. Here is the snapshot:

@ENTITY
@Table(name="TDepart")

class Department{

  private long id;

  @GeneratedValue(strategy= GenerationType.TABLE)

  public long getId();

}

//And some classes like

class Professor {
  void setDepartmentId(long id);
}

Now I have a business operation:

void doSomething()
{

  Department depart = new Department();

  handleProfessors (depart);
  handleStudent (depart);
  //and someother rountines need to refer department
}

//sample code which will getId
void handleProfessors(Department depart)
{

  Professor p = new Professor (); 

  p.setDepartmentId(depart.getId);

}

So the Department.getId() will be called several times. The doSomething() will be in a single managed transaction, but the GeneratedValue will use an unmanaged tx. Now may problem is: whenever the getId is called, it will return a new value, and when the department is final persisted, the id is the latest number, so all other objects refer to an non-exists department. Is there anyway to handle this so that the id is (kindof) persist?

I have a loose requirement solution, which will create an dummy department first and persist it, so the ID is not change. The code is similar to this:

void doSomething() 
{
  Department depart = createEmptyDepartment(); // always new tx so department is created;

  try { 
    reallyDoSomehing(); // tx required so it is part of global tx
  }
  catch (SomeException e) {
    removeEmptyDepartment(depart);
  }

Now I do not know how I can set the tx for removeEmptyDepartment(), if is required it will use the global request so it will be rollback as well. If it is new tx it will cause a deadlock since reallyDoSomething() will lock the db row.

Please, give me some ideas on how to solve it.

Thanks, Howard.

Upvotes: 0

Views: 889

Answers (1)

Samuel Parsonage
Samuel Parsonage

Reputation: 3127

I don't fully understand your issue, but I'm thinking that rather than setting the departmentId in your professor class, you should be setting the Department instead i.e.

 void setDepartmentId(long id);

change to

 void setDepartment(Department d);

The id components should be handled automatically by the entity manager

Upvotes: 3

Related Questions