JPA EntityManager不会在SQLite数据库中提交更改

时间:2015-10-12 18:28:57

标签: sqlite jpa transactions eclipselink entitymanager

我有一个SQLite数据库。我使用EclipseLink和JPA来处理它。另外,我有一个实体类User

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数据库我没有错误,但提交以某种方式失败。

1 个答案:

答案 0 :(得分:1)

我只是用hibernate等开发,但它会是相同的,因为它们都实现了JPA。 如果您启动事务,JPA将记住您在此事务中加载的所有实体,如果您更改了某些内容,您将看到db中的更改(提交后)。

但是在您的交易中,JPA无法识别您的实体,因此更改不会持续存在。尝试在事务中加载实体。像...

    em.getTransaction().begin();
        em.find(User.class, currentUser.getId()); //Reload the User from db, so it is attached to the session
        currentUser.setPassword(newPassword);
    em.getTransaction().commit();

有关方法的更多信息: