我有一個SQLite數據庫。我使用EclipseLink和JPA使用它。另外我有一個實體類User
:JPA EntityManager不會在SQLite數據庫中提交更改
import com.vaadin.server.VaadinService;
import java.io.Serializable;
import javax.persistence.*;
@Entity
public class User implements Serializable {
@Id @GeneratedValue
long id; // Unique identifier of the user in the DB
String username; // Unique name used for login
String password; // Password used for login
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public Long getId() {
return id;
}
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;
}
}
在登記表我創建了一個用戶,然後調用EntityManager
到persist()
的變化:
public int createUser(String username, String password, String password_confirmation) {
int regStatus = 0;
if(checkValidUsername(username)) {
if(checkValidPassword(password, password_confirmation)) {
EntityManager em = factory.createEntityManager();
try {
em.getTransaction().begin();
User user = new User(username, password);
em.persist(user);
em.getTransaction().commit();
}
catch(Exception e) {
System.out.println(e.getMessage());
regStatus = 3;
}
finally {
em.close();
}
}
else regStatus = 2; // Password mismatch
}
else regStatus = 1; // User with selected username already present in DB
return regStatus;
}
它的工作沒有任何問題。我在USER
表中獲得每個新註冊的用戶。但是,當我嘗試更改密碼時,它不起作用。下面是與此相關的程序方法:
// Inside the controller for my settings view - here the user can change various things related to his/her profile
public void setCurrentUser() {
currentUser = UserController.findUserByName((String)VaadinSession.getCurrent().getAttribute("username")); // findUserByName() is a static method
}
// Inside the User controller I have multiple methods for common user-related queries; here I use the username that I have retrieved from the VaadinSession's attribute "username" to execute a query and get the User entity (I make sure that a user's name is unique so getting a single result here is not a problem)
public static User findUserByName(String username) {
if(username == null) return null;
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
User user = null;
try{
Query q = em.createQuery("SELECT u FROM User u WHERE u.username = :username");
q.setParameter("username", username);
user = (User)q.getSingleResult();
}
catch(Exception e){
System.err.println(e.getMessage());
}
finally {
em.close();
}
return user;
}
// Inside the controller fpr my settings view (where I change the password)
public int changePassword(String currentPassword, String newPassword, String newPasswordConfirmation) {
if(newPassword.isEmpty()) return 1;
if(!newPassword.equals(newPasswordConfirmation)) return 2; // Incorrect confirmation
if(!currentPassword.equals(currentUser.getPassword())) return 3; // Given current password doesn't match the one stored in the database for this user
int resStatus = 0;
EntityManager em = factory.createEntityManager();
try {
em.getTransaction().begin();
currentUser.setPassword(newPassword);
em.getTransaction().commit(); // NO ERRORS at all...
}
catch(Exception e) {
System.out.println(e.getMessage());
resStatus = 4; // Exception
}
finally {
em.close();
}
return resStatus;
}
我也使用EntityManager.find(...)
,這應該從USER
表中返回同一行(和它),但結果又是同樣的嘗試 - 交易開始,完成後,實體經理關閉,但對於所謂的更改用戶表USER
是相同的。
任何想法?我在另一個項目中使用了相同的例程,但是用於設置其他項目。那裏的數據庫是PostreSQL,我還沒有遇到這樣的問題。在SQLite數據庫中,我沒有收到任何錯誤,但提交失敗了。
確實的EclipseLink提供SQLite的全力支持?我知道它並不習慣,而且我曾經使用DataNucleus,只要我想使用該數據存儲。查看EclipseLink日誌可能會顯示大量 –
當我觸發密碼更改時,我看不到任何事務提交。另外,我在哪裏可以找到有關EclipseLink支持SQLite的一些信息。我試着在這裏和那裏看,但沒有出現。不過我真的懷疑它會支持'persist()'(使用事務!),而不是列中某個值的簡單更改。我認爲這個錯誤是我給出的代碼中的其他地方。只是不知道在哪裏。調試完全沒有幫助,因爲我沒有任何錯誤。 – rbaleksandar
那麼,如果我搜索「Eclipselink支持的數據庫」,我會得到http://wiki.eclipse.org/EclipseLink/FAQ/JPA#What_databases_are_supported.3F –