Jpa 事务性CDIBean未将记录提交到数据库
我正在尝试使用JAX-RS构建一个简单的REST服务,该服务将在数据库表上执行标准CRUD操作。我能够成功查询记录,但无法插入新记录。我没有得到任何错误,当我在调试模式下逐步完成代码时,一切看起来都很好。我使用的是运行在Glassfish 4.1容器中的事务性CDIBean 感觉就像从来没有提交过交易。我对JavaEE相当陌生,但我的理解是,由于bean是事务性的,所以容器应该为我处理提交。有人知道为什么不是吗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
@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中配置:
元素链接persistence.xml中的数据源配置当您使用JTA事务管理时,创建和管理数据库连接的责任由应用程序服务器提供,而不是由您的应用程序提供 基本上,您必须在GlassFish服务器实例中配置数据源,而不是通过属性直接在persistence.xml中配置:
元素链接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>