0

2 つのエンティティに対して CRUD 操作を行う単純な SE アプリケーションを作成しています。両方のエンティティで主キーが自動インクリメントされることに気付きました。新しいオブジェクトを永続化するFirstEntityと ID = 1 が取得されますが、これは問題ありませんが、永続SecondEntity化し、その ID は 2 ですが、 type のエンティティが他にないため、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<>();
}

2 番目のエンティティ:

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

whereEmployeeDAO.create(Employee)を使用EntityManagerしてオブジェクトを永続化します

4

1 に答える 1

1

strategy = GenerationType.IDENTITYid-Columns で使用する必要があります。(テーブルの自動インクリメントを使用)。

strategy = GenerationType.AUTO使用可能なすべてのテーブルで共有される OWN Auto-increment コレクションから数値を選択して、休止状態 (または使用している JPA 実装) を作成します。

すべてのオプションについては、こちらを参照してください: 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;
于 2013-10-21T20:37:48.533 に答える