2013-10-21 100 views
0

我正在用兩個實體的CRUD操作編寫簡單的SE應用程序。我注意到兩個實體的主鍵都是自動遞增的。當我堅持FirstEntity的新對象時,它得到ID = 1,這很好,但是,我堅持SecondEntity,它的ID是2,但應該是1,因爲沒有其他SecondEntity類型的實體。什麼可能是這種發生的原因?主鍵爲所有實體遞增

第一實體:

@Entity 
@NamedQueries(value = { 
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e") 
}) 
public class Employee extends AbstractModel<Long, Employee>{ 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Basic 
@Column(name = "FIRST_NAME") 
private String firstName; 
@Basic 
@Column(name = "LAST_NAME") 
private String lastName; 
@Basic 
@Column(name = "ACCOUNT_NUMBER") 
private String accountNumber; 
@Column(name = "BIRTH_DATE") 
@Temporal(TemporalType.DATE) 
private Date birthDate; 

@ManyToMany(cascade = CascadeType.REMOVE) 
@JoinTable(name = "EMP_TASK", joinColumns = {@JoinColumn(name = "EMP_ID", referencedColumnName = "ID")}, 
     inverseJoinColumns = {@JoinColumn(name = "TASK_ID", referencedColumnName = "ID")}) 
private Set<Task> tasks = new HashSet<>(); 
} 

第二實體:

@Entity 
@NamedQueries(value = { 
@NamedQuery(name = "Task.findFinished", query = "SELECT t FROM Task t where t.endDate <= :date"), 
@NamedQuery(name = "Task.findActive", query = "SELECT t FROM Task t where t.startDate <= :date and :date <= t.endDate"), 
@NamedQuery(name = "Task.findAll", query = "SELECT t FROM Task t") 
}) 
public class Task extends AbstractModel<Long, Task>{ 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Basic 
private String name; 
@Column(name = "START_DATE") 
@Temporal(TemporalType.DATE) 
private Date startDate; 
@Column(name = "END_DATE") 
@Temporal(TemporalType.DATE) 
private Date endDate; 

@ManyToMany(mappedBy = "tasks", cascade = CascadeType.REMOVE) 
private Set<Employee> employees = new HashSet<>(); 
} 

抽象模型:

public abstract class AbstractModel<ID extends Serializable, T extends AbstractModel<ID, T>> implements Serializable { 

private Class<T> modelClass; 

abstract public ID getId(); 

/** 
* Default construcot initializing class field. 
*/ 
public AbstractModel(){ 
    modelClass = resolveModelClass(); 
} 

/** 
* Default {2code equals(Object obj)| function for all entities 
* @param obj 
*  object to be compared 
* @return 
*  true if object are eqaul, false otherwise 
*/ 
@Override 
public boolean equals(Object obj){ 
    if(!modelClass.isInstance(obj)) 
     return false; 

    T other = modelClass.cast(obj); 
    if ((this.getId() == null && other.getId() != null) || (this.getId() != null && !this.getId().equals(other.getId()))) { 
     return false; 
    } 

    return true; 
} 

@Override 
public int hashCode(){ 
    return (getId() != null ? getId().hashCode() : 0); 
} 

@Override 
public String toString(){ 
    return modelClass.getName() + "[ id=" + getId() + " ]"; 
} 

private Class<T> resolveModelClass(){ 
    return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1]; 
} 

}

堅持方法:

private static void addNewEmployee() { 
    Employee emp = new Employee(); 
    // setting fields of emp 

    EmployeeDAO empDAO = new EmployeeDAOImpl(); 
    emp = empDAO.create(emp); 
    if (emp != null) { 
     System.out.println("New employee with ID: " + emp.getId() + " has been saved"); 
    } else { 
     System.out.println("A problem occured while trying to persist employee entity"); 
    } 
} 

其中EmployeeDAO.create(Employee)使用EntityManager堅持對象

+0

你能否提供一些源代碼? – reporter

+0

提供'hbm.xml'或'註釋類' – nachokk

+0

對不起,麻煩你。我有一個停電,我一直在想,GenerationType.AUTO將作爲GenerationType.IDENTITY。但是,我使用的是NetBeans提供的Apache Derby,它看起來像AUTO一樣工作。此外,由於拋出了SQLIntegrityConstraintViolationException,因此IDENTITY不適用於Derby – Nav

回答

1

你應該在ID-列使用strategy = GenerationType.IDENTITY。 (使用表的自動增量)。

strategy = GenerationType.AUTO將使hibernate(或您正在使用的任何JPA實現)從其所有可用表共享的OWN自動增量集合中挑選一個數字。

在這裏看到的所有選項:http://docs.oracle.com/javaee/5/api/javax/persistence/GenerationType.html

更新由於評論:

你可以嘗試使用GenerationType.Sequence

@Id 
@SequenceGenerator(name="sequence1", allocationSize=1, initialValue=1) 
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="sequence1") 
private long id; 
+0

不幸的是,Apache Derby沒有提供'GenerationType.IDENTITY',我們必須處理它,因爲類的目的 – Nav

+1

@Nav你可以嘗試使用'GenerationType.Sequence'。查看我的帖子的更新。 – dognose

+0

祝福你。這非常有幫助,Apache Derby接受它;) – Nav