2013-02-22 49 views
1

我是新來的JPA和我在與從存儲庫此示例代碼的一個問題:JPA如何調用合併或持續

@Override 
public boolean add(User user) { 
    EntityManagerFactory emf = HibernateRepositoryFactory 
      .getEntityManagerFactory(); 
    EntityManager em = emf.createEntityManager(); 
    EntityTransaction tx = em.getTransaction(); 
    tx.begin(); 

    User tempUser = null; 
    try { 
     if (user.getId() != null) { 
      tempUser = em.find(User.class, user.getId()); 
     } 
     if (tempUser == null) { 
      em.persist(user); 
     } else { 
      // if so, get the differences and persist them 
      tempUser.setPassword(user.getPassword()); 
      tempUser.setUserName(user.getUserName()); 
      tempUser = em.merge(user); 
     } 
    } catch (Exception e) { 
     logging.error("log error+ " :" + e); 
    } 
    tx.commit(); 
    em.close(); 
    emf.close(); 
    return true; 
} 

與實體:

@Entity 
@Table(name = "USERS") 

public class User implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column(name = "ID", nullable = false, unique = true) 
private Long id; 

@Version 
@Column(name = "OPTLOCK") 
private int version; 

@Column(name = "USERNAME", nullable = false) 
private String userName; 

@Column(name = "PASSWORD", nullable = false) 
private String password; 

public User() { 
    super(); 
} 

public String getUserName() { 
    return userName; 
} 

public void setUserName(String userName) { 
    this.userName = userName; 
} 

public String getPassword() { 
    return password; 
} 

public void setPassword(String password) { 
    this.password = password; 
} 

public Long getId() { 
    return id; 
} 

public int getVersion() { 
    return version; 
} 

}

我完全不理解它。

在行:if(user.getId()!= NULL)user.getId永遠是零,因爲我相信,ID將此刻的對象將被持久化生成?像這樣tempUser將永遠不會從數據庫中填充,並且對象將始終保持不被合併....或者我看到這個錯誤?

什麼會看到,如果你需要保留或合併這樣的最佳方式。

編輯

,如果我會用什麼主這樣的:

User user1 = new User(); 

    user1 .setPassword("password_user1"); 
    user1 .setUserName("userName_user1"); 

... .add(user1); 

如果我跑這一次的用戶加入。如果我然後再次運行此用戶再次堅持一個ID + 1

+0

如果Id是已修改的分離實體,則Id可能不爲null。 – SJuan76 2013-02-22 13:42:11

+0

@ Sjuan76就我所見,我沒有看到分離。如果我使用這個方法添加一個User對象並且我運行了兩次,那麼2個用戶將在我的數據庫中,而不是一個...。 – 2013-02-22 13:48:16

+0

您只會顯示一小部分程序。該邏輯使用代碼更新現有實體或保留新實體。前者最好通過檢索實體並將其分離來完成(因此,您不需要等待UI過多時間)。 – SJuan76 2013-02-22 14:03:34

回答

1

你是對的,如果用戶參數是新的(從未被持續),那麼這種方法將persist()它。如果它是一個分離的實例(已經被保存,並且有一個id),它將通過調用merge()來更新它。

我覺得這個方法的名稱是一種誤導,它應該是叫saveOrUpdate()

+0

同意。這將是一個更好的名字 – 2013-02-22 13:43:42

+0

hmmm .. getid()是實體的一種方法。此刻我創建這個對象它將是空的。他怎麼能看到該對象是否已經在db中完成而沒有調用db。或者我看到這個錯誤 – 2013-02-22 13:50:37

+0

如果您手動設置用戶的ID,並且恰好是db中現有用戶的ID,則該方法將更新該現有用戶,而不是創建新用戶。它背後並沒有什麼神奇的東西可以將手工製作的用戶對象與「真正的」獨立實體區分開來。 – zagyi 2013-02-22 13:55:47

0

如果方法參數User是持久實體,則getId()將不爲null。

+0

他將如何得到這個ID?我調用一個實體的方法,而不是搜索數據庫? – 2013-02-22 13:44:48

+0

add方法應該是DAO或Repository類的方法。考慮一種情況,我在另一個方法中將用戶實體加載到另一個hibernate會話中,然後使用該對象調用此方法,此時該對象已分離,並且getId()調用不會爲空。 – 2013-02-22 13:51:34

+0

我用這個實體和這個方法嘗試了這個。如果我創建一個主要的方法,用密碼和用戶名創建一個新的用戶對象,並使用這種方法來實現它。第一次添加用戶對象時,當我再次運行主,用戶添加一個ID + 1,但其餘的都是一樣的? – 2013-02-22 13:55:53