简体   繁体   中英

Getting an EJBTransactionRolledbackException when trying to connect to a MYSQL database

I'm trying to functionality to login with credentials from the database. So far I've just been getting an EJBTransactionRolledbackException. The stack trace is huge and so far I have not been able to find anything online related to my specific issue.

So the MySQL database I have set up has tables divided up into logical data. I have a user_info table with a memberID, addressID, loginID, firstName, lastName, email, phoneNumber, and isModerator. My user_login table has loginID, username, and password. The user_address table is not necessary at this point in the program. The loginID from the user_login table is a foreign key in the user_info table. So I essentially do an inner join to get all the info from bot tables and then try to create a new user object and return it. I've tried just pulling data from one table but the same issue persists. The query being used in the Java code works just fine in MySQL workbench.

Here is the method in question, it's the findEntry method:

@Stateless
@Local(DataAccessInterface.class)
@LocalBean
public class UserDataService implements DataAccessInterface<User> {

    public UserDataService() {



    }

    @Override
    public List<User> findAll() {

        return null;

    }

    @Override
    public User findEntry(String condition) {

        String query = "SELECT * FROM user_info INNER JOIN user_login WHERE username='" + condition + "';";

        Connection databaseConnection = null;

        Statement statement = null;

        ResultSet resultSet = null;

        User currentUser = null;

        try {

            databaseConnection = DriverManager.getConnection(url, username, password);

            statement = databaseConnection.createStatement();

            resultSet = statement.executeQuery(query);

            currentUser = new User(resultSet.getInt("memberID"), resultSet.getInt("addressID"), resultSet.getInt("loginID"), resultSet.getString("firstName"), resultSet.getString("lastName"), resultSet.getString("email"), resultSet.getString("phoneNumber"), resultSet.getString("username"), resultSet.getString("password"), resultSet.getInt("isModerator"));

        }

        catch(SQLException e) {

            throw new DatabaseException(e);

        }

        finally {

            try {

                if(databaseConnection != null) {

                    databaseConnection.close();

                    statement.close();

                    resultSet.close();  

                }


            }

            catch(SQLException e) {

                throw new DatabaseException(e);

            }

        }

        return currentUser;

    }

Here is where the findEntry is being called:

@Stateless
@Local(AccountBusinessInterface.class)
@LocalBean
public class AccountBusiness implements AccountBusinessInterface {

    @EJB
    private DataAccessInterface<User> userDataService;

    public AccountBusiness() {



    }

    /**
     * Validates that the use who entered in their username and password entered the correct information.
     */
    @Override
    public int validateUser(User user) {
        //Sets the login boolean to true.
        //user.setLoggedIn(true);
        //Sets the login text to logout.
        //user.setLoginText("Logout");

        User currentUser = userDataService.findEntry(user.getUsername());

        if(currentUser !=  null) {

            return 0;

        }

        return 1;

    }

This is the onLogin method in the login controller:

@ManagedBean
@ViewScoped
public class LoginController {

    /**
     * This is the BusinessAccountInferface.
     */
    @Inject
    private AccountBusinessInterface accountBusinessInterface;

    /**
     * The default constructor.
     */
    public LoginController() {



    }

    /**
     * Takes in a user object and returns the product page that can only be seen by a logged in user, assuming the correct
     * username and password was entered.
     * @param user
     * @return String
     */
    public String onLogin(User user) {
        //Gets the user object from the appropriate form.

FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("user", user); //If authentication fails, returns the error page. if(accountBusinessInterface.validateUser(user) == 0) { //Return the products page. return "ProductsPage.xhtml";

        }
        //Returns the login page by default.
        return "Login.xhtml";

    }

Here is my custom exception:

public class DatabaseException extends RuntimeException {

    /**
     * This is the default serial version id.
     */
    private static final long serialVersionUID = 1L;

    public DatabaseException() {

        printStackTrace();

    }

    public DatabaseException(SQLException e) {

        printMessage(e.getMessage());

    }

    public DatabaseException(String message) {

        printMessage(message);

    }

    public DatabaseException(SQLException e, String message) {

        printMessage(e.getMessage());

        printMessage(message);

    }

    private void printMessage(String message) {

        System.err.println(message);

    }

}

The stack trace is too long, but here are the first two lines:

19:11:22,668 ERROR [stderr] (default task-18) Before start of result set

19:11:22,671 ERROR [org.jboss.as.ejb3.invocation] (default task-18) WFLYEJB0034: EJB Invocation failed on component UserDataService for method public beans.User data.UserDataService.findEntry(java.lang.String): javax.ejb.EJBTransactionRolledbackException

The rest of the stack trace is in a file here since I couldn't paste it here: https://www.dropbox.com/s/r4ampjxr7clfzjz/log.txt?dl=0

The expected result is that a user will be returned from the findEntry method, which is checked in the validateUser method on the business logic, and if it does not return null then 0 is returned which is checked in the login controller which should log the user in. Obviously something is wring with the database being rolled back. I'm just not sure what that means or what is causing it to happen or how to fix it. Did I leave any important code or xml files out?

You have to move the curser in the result set first, this is what the error message " Before start of result set " is telling you.

So move the curser first before reading from it. ResultSet#next() will return true if it is not already at the end.

if (resultSet.next()){
    currentUser = new User(resultSet.getInt("memberID")...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM