Jave Rest-api与JPA,H2在内存中并部署在Wildfly上:由于事务和自动提交,无法PUT和POST

bf1o4zei  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(150)

我正在构建一个用于维护用户的Rest-api服务。它非常简单,但我有两个主要的限制:

  • 使用的数据库必须在内存中
  • 必须部署在Wildfly上

对于内存数据库,我使用H2,正如您在我的persistence.xml中看到的:

<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_1.xsd"
             version="3.0">

    <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
        <!-- Entity classes -->
        <class>com.xxxx.business.User</class>
        <class>com.xxxx.business.Gender</class>

        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.url"    value="jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'src/main/resources/h2init.sql';DB_CLOSE_DELAY=-1;"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <property name="hibernate.show_sql" value="true"/>

            <property name="hibernate.connection.autocommit" value="true" />

            <property name="javax.persistence.schema-generation.database.action"
                      value="drop-and-create" />
            <property name="javax.persistence.sql-load-script-source"
                      value="/h2init.sql" />
        </properties>

    </persistence-unit>
</persistence>

字符串
我使用RESOURCE_REPORT事务和一个脚本插入到我的DB中。到目前为止,它工作得很好。
我的POJO很常见:

import jakarta.ejb.TransactionManagement;
import jakarta.ejb.TransactionManagementType;
import jakarta.enterprise.inject.Model;
import jakarta.persistence.*;

import java.io.Serializable;
import java.util.Date;

@Entity
@Model
@TransactionManagement(TransactionManagementType.BEAN)
@Table(name = "UserApi")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_ID")
    private long id;
    @Column(name = "FIRST_NAME")
    private String firstName;
    @Column(name = "LAST_NAME")
    private String lastName;
    @Column(name = "EMAIL")
    private String email;
    @Column(name = "BIRTHDAY")
    private Date birthday ;
    @Column(name = "PASSWORD")
    private String password;

    public User(String firstName, String lastName, String email, Date birthday, String password) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.birthday = birthday;
        this.password = password;
    }

    public User() {
        super();
    }

    public long getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getPassword() {
        return password;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", birthday=" + birthday +
                ", password='" + password + '\'' +
                '}';
    }
}


以下是我的资源:

import jakarta.inject.Inject;
import jakarta.transaction.SystemException;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

@Path("/users")
@Produces("application/json")
@Consumes("application/json")
public class UserResource {
    @Inject
    UserService userService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    @GET
    @Path("/sf/{firstName}")
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getUsersByFirstName(@PathParam("firstName")String firstName) {
        if(!StringUtils.isAllEmpty(firstName)){
            return userService.getUsersByFirstName(firstName);
        }
        return userService.getAllUsers();
    }

    @GET
    @Path("/si/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public User getUser(@PathParam("id")long id) {
        return userService.getUserById(id);
    }

    @PUT
    @Path("/u")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Transactional
    public Response updateCustomer(User user) {
        userService.updateUser(user);
        return Response.status(204).build();
    }

    @POST
    @Path("/c")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Transactional
    public Response create(User user) {
        userService.createUser(user);
        return Response.status(201).build();
    }
}


我的服务:

import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.inject.Inject;
import jakarta.persistence.*;
import jakarta.transaction.*;
import jakarta.transaction.RollbackException;
import jakarta.ws.rs.WebApplicationException;

import java.util.List;
//import java.util.logging.Logger;

public class UserService {
    //private static final Logger LOGGER = Logger.getLogger(UserService.class.getName());
    private static final String getAllUsers = "select u from User u";
    private static final String getUsersByFirstNameSql = "select u from User u where u.firstName=:firstName";
    private static final String getUsersByLastNameSql = "select u from User u where u.lastName=:lastName";
    private static final String getUserByIdSql = "select u from User u where id=:id";

    @PersistenceContext
    EntityManager em;

    public void createUser(User user) {


        try {
            em.getTransaction().begin();
            em.persist(user);
            em.getTransaction().commit();
            em.close();
        } catch (IllegalStateException  e) {
            em.getTransaction().rollback();
        }
        //LOGGER.info("Created user "+user);
    }

    public void updateUser( User user ) {
        em.getTransaction().begin();
        User u = getUserById(user.getId());
        u.setFirstName(user.getFirstName());
        u.setLastName(user.getLastName());
        u.setBirthday(user.getBirthday());
        u.setEmail(user.getEmail());
        u.setPassword(user.getPassword());
        em.persist(u);
        em.getTransaction().commit();
        em.close();
        //LOGGER.info("Updated user" + user);
    }

    public void deleteUser(Long id) {
        User user = getUserById(id);
        em.remove(user);
        //LOGGER.info("Deleted User with id" + id);
    }
    public User getUserById(Long id) {
        User user = em.find(User.class, id);
        if (user == null) {
            throw new WebApplicationException("User with id of " + id + " does not exist.", 404);
        }
        return user;
    }
    public List<User> getAllUsers() {
        List<User> users = em.createQuery(getAllUsers, User.class).getResultList();
        return users;
    }
    public List<User> getUsersByFirstName(String firstName){
        List<User> users = em.createQuery( getUsersByFirstNameSql, User.class)
                .setParameter("firstName", firstName).getResultList();
        return users;
    }

}


问题是,如果我不使用transaction,我根本不能持久化。所以,我从我的事务管理器获取一个transaction。结果,我得到一个“java.sql.SQLException:IJ 031017:You cannot set autocommit during a managed transaction”。
尝试在持久化中添加AUTOCOMMIT = false(无论是在hibernate中还是在jdbc h2中)都没有任何效果。
在此先谢谢您!

iyr7buue

iyr7buue1#

我通过修改wildfly文件夹上的standalone.xml配置文件来解决我自己的问题。你必须在你使用的文件夹上添加jta=“false”<jta=“false”....>。
更多信息:https://www.mastertheboss.com/jbossas/jboss-datasource/demystifying-datasource-jta-and-xa-settings-on-jboss-wildfly/
希望有一天能帮助到别人。

相关问题