java - 尝试让 JPA/Hibernate 与 REST 配合使用 - TransactionRequiredException : No Transaction is in progress error

标签 java mysql spring hibernate jpa

我一直在尝试让 Hibernate/JPA 与我的简单 Spring 3.2 REST 应用程序一起工作。

Hibernate/JPA 在 MySQL 中成功创建了我的表,但是事务一旦进入存储库就会失败 - 表示没有事务正在进行。我真的不适应这里,甚至不知道如何解决这个问题,因为似乎大部分代码都是在 xml 的幕后发生的。

非常感谢任何帮助。 更新——jpaContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<context:annotation-config />
<context:component-scan base-package="com.saltcitywifi"></context:component-scan>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="punit" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
            <property name="showSql" value="true" />
        </bean>
    </property>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <entry key="hibernate.hbm2ddl.auto" value="create" />
            <entry key="hibernate.format_sql" value="true" />
        </map>
    </property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />

</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/salt_city_wifi?autoReconnect=true" />
    <property name="username" value="wifi_admin" />
    <property name="password" value="password" />
</bean>

Controller :

@Controller
public class HotSpotController {
@Autowired
private HotSpotService hotSpotService;

@RequestMapping(value = "/hotSpots", method = RequestMethod.GET)
public @ResponseBody
List<HotSpot> getHotSpots() {
    hotSpotService = new HotSpotServiceImpl();
    List<HotSpot> spots = hotSpotService.getAllHotSpots();
    return spots;
}

@RequestMapping(value = "/hotSpot", method = RequestMethod.POST)
public @ResponseBody
HotSpot addHotSpot(@RequestBody HotSpot hotSpot) {
    hotSpotService.addHotSpot(hotSpot);
    return hotSpot;
}

}

服务:

@Service("hotSpotService")
@Transactional
public class HotSpotServiceImpl implements HotSpotService {
@Autowired
private HotSpotRepository hotSpotRepository;
private AtomicLong counter = new AtomicLong();

public List<HotSpot> getAllHotSpots() {
    List<HotSpot> spots = new ArrayList<HotSpot>();
    HotSpot spot;
    for (int i = 0; i < 10; i++) {
        spot = new HotSpot("location " + i, "http://www.url" + i + ".com",
                counter.incrementAndGet());
        spots.add(spot);
    }
    return spots;
}

public HotSpot getHotSpotById(long id) {
    HotSpot spot = new HotSpot("New Spot", "New Url", id);
    return spot;
}

@Transactional
public HotSpot addHotSpot(HotSpot hotSpot) {
    return hotSpotRepository.addHotSpot(hotSpot);

}

}

@Repository("hotSpotRepository")
public class HotSpotRepositoryImpl implements HotSpotRepository {
@PersistenceContext
private EntityManager em;


public HotSpot addHotSpot(HotSpot hotSpot) {
    em.persist(hotSpot);
    em.flush();
    return hotSpot;
}

}

最佳答案

好吧,我终于弄清楚这里发生了什么:

我有两个组件扫描器,一个用于 servlet-config.xml 中的 Controller ,另一个用于 jpaContext.xml 中的 JPA 内容。

他们基本上都在扫描我的整个申请:

<context:component-scan base-package="com.saltcitywifi" />

当我强制 Controller 的组件扫描器仅查看 Controller 包时:

<context:component-scan base-package="com.saltcitywifi.controller" />

突然之间,我的请求生效并在数据库中得到处理。

我只能假设,因为我的 servlet-config.xml 配置仅包含:

<context:component-scan base-package="com.saltcitywifi.controller" />
<mvc:annotation-driven />

Spring 以某种方式让 servlet-config.xml 注册 JPA bean,因此事务注释没有被拾取。这仍然让我感到困惑,所以如果有人能帮助解释为什么会发生这种情况,那将会非常有帮助。我可能会问关于这个主题的另一个堆栈溢出问题。

关于java - 尝试让 JPA/Hibernate 与 REST 配合使用 - TransactionRequiredException : No Transaction is in progress error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24397273/

相关文章:

java - 如何在不是已配置 bean 的类中 Autowiring bean?

java - 如何在不破坏资源映射的情况下隐式映射文件夹 View ?

java - 有没有办法在启动 mvn appengine :devserver? 时不运行单元测试

java - 是否可以使用 PrintWriter 在某一行之后开始写入文件?

java - 在 jsf 标签内调用 if 函数两次

php - Mysql相似文搜索

php - PHP 中的个人资料图片保存选项

java - Spring Web MVC Tiles 异常

java - 获取要在 JUnit 5 中执行的测试类列表

mysql 存储过程更新所有行而不是 1