Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 事务性CDIBean未将记录提交到数据库_Jpa_Jakarta Ee_Cdi - Fatal编程技术网

Jpa 事务性CDIBean未将记录提交到数据库

Jpa 事务性CDIBean未将记录提交到数据库,jpa,jakarta-ee,cdi,Jpa,Jakarta Ee,Cdi,我正在尝试使用JAX-RS构建一个简单的REST服务,该服务将在数据库表上执行标准CRUD操作。我能够成功查询记录,但无法插入新记录。我没有得到任何错误,当我在调试模式下逐步完成代码时,一切看起来都很好。我使用的是运行在Glassfish 4.1容器中的事务性CDIBean 感觉就像从来没有提交过交易。我对JavaEE相当陌生,但我的理解是,由于bean是事务性的,所以容器应该为我处理提交。有人知道为什么不是吗 @Path("/recipes") @Consumes(MediaType.APPL

我正在尝试使用JAX-RS构建一个简单的REST服务,该服务将在数据库表上执行标准CRUD操作。我能够成功查询记录,但无法插入新记录。我没有得到任何错误,当我在调试模式下逐步完成代码时,一切看起来都很好。我使用的是运行在Glassfish 4.1容器中的事务性CDIBean

感觉就像从来没有提交过交易。我对JavaEE相当陌生,但我的理解是,由于bean是事务性的,所以容器应该为我处理提交。有人知道为什么不是吗

@Path("/recipes")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class RecipeResource {
    @Inject
    RecipesService recipesService;

    @GET
    public List<Recipe> getRecipes() {
        return recipesService.getAllRecipes();
    }

    @POST
    public void addRecipse(Recipe recipe) {
        recipesService.addRecipe(recipe);
    }

}

public class RecipesService {
    @PersistenceContext(unitName="PANTRYDB", type=PersistenceContextType.TRANSACTION)
    EntityManager em;

    public RecipesService () {

    }

    public List<Recipe> getAllRecipes () {
        List<Recipe> recipes = null;

        try {
            TypedQuery<Recipe> typedQuery = em.createQuery("select r from Recipe r", Recipe.class);

            recipes = typedQuery.getResultList();
        } catch (Exception e) {
            System.out.println(e);
        }

        return recipes;
    }

    @Transactional
    //This is the method that seems to not commit it's transaction
    //The Recipe object is populated correctly, and the persist() doesn't 
    //throw any errors
    public void addRecipe(Recipe recipe) {
        try {
            em.persist(recipe);
        } catch (Exception e) {
            System.out.println(e);
        }
    }

}

@Entity
@Table(name="RECIPES", schema="COOKBOOK")
public class Recipe {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    @Column
    private String name;

    @Column(name="CREATED_DATE")
    private Calendar createdDate;

    @Column(name="LAST_MADE_DATE")
    private Calendar lastMadeDate;

    @Column
    private String description;

    @Column
    private String notes;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Calendar getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Calendar createdDate) {
        this.createdDate = createdDate;
    }

    public Calendar getLastMadeDate() {
        return lastMadeDate;
    }

    public void setLastMadeDate(Calendar lastMadeDate) {
        this.lastMadeDate = lastMadeDate;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    @Override
    public String toString() {
        return name;
    }
}
@Path(“/recipes”)
@使用(MediaType.APPLICATION_JSON)
@产生(MediaType.APPLICATION_JSON)
公共类ReciperSource{
@注入
菜谱服务菜谱服务;
@得到
公共列表getRecipes(){
return recipesService.getAllRecipes();
}
@职位
公共无效添加配方(配方){
配方服务。添加配方(配方);
}
}
公共类服务{
@PersistenceContext(unitName=“PANTRYDB”,type=PersistenceContextType.TRANSACTION)
实体管理器;
公共服务(){
}
公共列表getAllRecipes(){
列表配方=空;
试一试{
TypedQuery TypedQuery=em.createQuery(“从配方r中选择r”,配方.class);
recipes=typedQuery.getResultList();
}捕获(例外e){
系统输出打印ln(e);
}
返回食谱;
}
@交易的
//这是一个似乎不提交其事务的方法
//配方对象已正确填充,而persist()未正确填充
//有错误吗
公共无效添加配方(配方配方){
试一试{
em.persist(配方);
}捕获(例外e){
系统输出打印ln(e);
}
}
}
@实体
@表(name=“RECIPES”,schema=“COOKBOOK”)
公共课食谱{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有int-id;
@纵队
私有字符串名称;
@列(name=“创建日期”)
私有日历创建日期;
@列(name=“上次制作日期”)
最后制作的私人日历;
@纵队
私有字符串描述;
@纵队
私人弦乐;
公共int getId(){
返回id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共日历getCreatedDate(){
返回createdDate;
}
公共void setCreatedDate(日历createdDate){
this.createdDate=createdDate;
}
公共日历getLastMadeDate(){
最后一次返回;
}
公共无效setLastMadeDate(日历lastMadeDate){
this.lastMadeDate=lastMadeDate;
}
公共字符串getDescription(){
返回说明;
}
公共void集合描述(字符串描述){
this.description=描述;
}
公共字符串getNotes(){
回条;
}
公共无效设置注释(字符串注释){
this.notes=注释;
}
@凌驾
公共字符串toString(){
返回名称;
}
}
Persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="PANTRYDB" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>com.domain.Recipe</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />      
            <property name="javax.persistence.jdbc.url" value="jdbc:derby:/Users/development/eclipse/ws_playground/databases/pantry_db/PANTRYDB" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
            <property name="javax.persistence.jdbc.user" value=""/>
            <property name="javax.persistence.jdbc.password" value=""/>
        </properties>
    </persistence-unit>
</persistence>

org.hibernate.jpa.HibernatePersistenceProvider
com.domain.Recipe

当您使用JTA事务管理时,创建和管理数据库连接的责任由应用程序服务器提供,而不是由您的应用程序提供

基本上,您必须在GlassFish服务器实例中配置数据源,而不是通过属性直接在persistence.xml中配置:

  • 在GlassFish服务器实例中配置连接池和数据源JNDI名称
  • 通过
    元素链接persistence.xml中的数据源配置
  • 请检查此答案以了解更多详细信息:

    当您使用JTA事务管理时,创建和管理数据库连接的责任由应用程序服务器提供,而不是由您的应用程序提供

    基本上,您必须在GlassFish服务器实例中配置数据源,而不是通过属性直接在persistence.xml中配置:

  • 在GlassFish服务器实例中配置连接池和数据源JNDI名称
  • 通过
    元素链接persistence.xml中的数据源配置
  • 请检查此答案以了解更多详细信息:

    您确定没有混合使用两种框架吗。RecipeResource有一个来自JavaEE框架的@Path注释,而@Transactional注释来自Spring框架,我认为您应该用@TransactionaAttribute替换它,后者是等价的JavaEE注释


    查看Spring中事务和JavaEE之间的详细信息,您确定没有混合使用两个框架吗。RecipeResource有一个来自JavaEE框架的@Path注释,而@Transactional注释来自Spring框架,我认为您应该用@TransactionaAttribute替换它,后者是等价的JavaEE注释


    查看Spring中事务与JavaEE之间的详细信息我在weblogic 12.2.1上尝试了您的应用程序,它成功地插入了数据库,我对事务没有任何问题

    这是我的密码

    RecipeResource
    类(我修改了
    @Path
    以通过web浏览器调用它,并手动实例化了
    配方
    ):

    我的
    persistence.xml
    (我正在使用内存数据库):

    
    org.eclipse.persistence.jpa.PersistenceProvider
    jdbc/_默认值
    org.jvi.webservice.transactional.db.Recipe
    
    @Path("/recipes")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    
    public class RecipeResource {
    
        @Inject
        RecipesService recipesService;
    
        @GET
        @Path("get")
        public List<Recipe> getRecipes() {
            return recipesService.getAllRecipes();
        }
    
        @GET
        @Path("add")
        public String addRecipse() {
            Recipe recipe = new Recipe();
            recipe.setDescription("desc");
            recipesService.addRecipe(recipe);
            return "OK";
        }
    
    }
    
    @Entity
    @Table(name="RECIPES") //, schema="COOKBOOK")
    public class Recipe {
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns    /persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
                 version="2.0">
    
       <persistence-unit name="PANTRYDB" transaction-type="JTA">
                <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/__default</jta-data-source>
        <class>org.jvi.webservice.transactional.db.Recipe</class>
        <properties>
            <!--<property name="eclipselink.ddl-generation" value="create-tables"/>-->
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
            <property name="eclipselink.logging.level" value="FINE"/>
            <property name="eclipselink.logging.level.sql" value="FINE"/>
            <property name="eclipselink.logging.parameters" value="true"/>
            <property name="eclipselink.logging.logger" value="DefaultLogger"/>
            <property name="eclipselink.cache.shared.default" value="false"/>
        </properties>
    </persistence-unit>