У меня есть база данных 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 –