Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.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
Java 试图让JPA/Hibernate与REST一起工作--TransactionRequiredException:没有正在进行的事务错误_Java_Mysql_Spring_Hibernate_Jpa - Fatal编程技术网

Java 试图让JPA/Hibernate与REST一起工作--TransactionRequiredException:没有正在进行的事务错误

Java 试图让JPA/Hibernate与REST一起工作--TransactionRequiredException:没有正在进行的事务错误,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,我一直在尝试让Hibernate/JPA使用我的简单Spring3.2REST应用程序 Hibernate/JPA成功地在MySQL中创建了我的表,但是一旦事务进入存储库,它就会失败——表示没有任何事务正在进行中。我真的不了解这里的内容,甚至不知道如何解决这个问题,因为大多数代码似乎都是在xml的幕后进行的 非常感谢您的帮助。 更新--jpaContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http

我一直在尝试让Hibernate/JPA使用我的简单Spring3.2REST应用程序

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
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;
}

}
@控制器
公共类热点控制器{
@自动连线
专用热点服务热点服务;
@RequestMapping(value=“/hospots”,method=RequestMethod.GET)
公共@ResponseBody
列出getHotSpots(){
hotSpotService=新的HotSpotServiceImpl();
List spots=hostpointservice.getAllHotSpots();
返回点;
}
@RequestMapping(value=“/hotSpot”,method=RequestMethod.POST)
公共@ResponseBody
热点addHotSpot(@RequestBody热点){
hotSpotService.addHotSpot(热点);
返回热点;
}
}
服务:

@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;
}

}
@Service(“热点服务”)
@交易的
公共类HotSpotServiceImpl实现HotSpotService{
@自动连线
私人温泉疗养院温泉疗养院;
私有AtomicLong计数器=新的AtomicLong();
公共列表getAllHotSpots(){
列表点=新的ArrayList();
热点;
对于(int i=0;i<10;i++){
spot=新热点(“位置”+i,”http://www.url“+i+”.com”,
counter.incrementAndGet());
点。添加(点);
}
返回点;
}
公共热点getHotSpotById(长id){
热点点=新热点(“新热点”、“新Url”、id);
返回点;
}
@交易的
公共热点addHotSpot(热点热点热点){
返回hospotrepository.addhospot(热点);
}
}
@存储库(“热点存储库”)
公共类HotSpotRepositoryImpl实现HotSpotRepository{
@持久上下文
私人实体管理者;
公共热点addHotSpot(热点热点热点){
em.persist(热点);
em.flush();
返回热点;
}
}

好的,我终于弄明白这里发生了什么:

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

他们都在扫描我的整个应用程序:

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

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

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

突然间,我的请求成功了,并在数据库中得到了处理

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

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


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

请在这里发布您的spring配置文件。您需要在配置中配置注释驱动、tx:transaction等以使其正常工作。。还将@transactional上的传播设置为requires
hospotservice=new hospotserviceinpl()这样做将创建一个类的实例,Spring对此一无所知。拆下那条线<代码>@Autowired private hospotrepository hospotrepository应该足够了,因为Spring将只创建一个HotSpotRepository实例并将其注入控制器中。当您自己处理这个问题时(通过手动创建那个实例),Spring将无法帮助您(例如,通过向方法添加事务)@Zeus我用我的jpaContext.xml更新了这篇文章。如果您想查看其他配置文件,请告诉我。@Andreestfan我删除了对new的调用,但实际上我还没有在控制器中使用该方法。我只在POST请求下进行了/hotSpot路由的工作。我仍然有相同的错误--没有正在进行的事务错误。谢谢你们两位的帮助,希望我能了解到底。这是我的完整代码:-)问题是
servlet context.xml
扫描所有包,它会找到控制器和服务,但对于服务,即使您有@Transactional,它缺少xml文件中实际的
transactionManager
tx:annotation-driven
。因此,在控制器中,您得到了一个简单的@servicebean,没有@Transactional行为。在
jpa context.xml中扫描另一个组件并不重要,因为一切都是从使用流中的控制器开始的:您访问网页,调用控制器,控制器调用服务,服务不是事务性的。谢谢,@andrestefan,这很有意义,我将更新我的问题和答案,试图为可能有同样问题的其他人澄清情况。我想知道的一件事是:我只是通过猜测解决了这个问题——有没有更好的调试方法,这样我就可以在将来遇到另一个冲突的配置问题时看到发生了什么?调试这些.xml文件对我来说是一个完全神秘的过程。您可以在调试日志中查找与应用程序上下文相关的消息。存在已创建的根应用程序上下文。还有一个web应用程序上下文,它的父上下文是根上下文。在日志中,您应该可以看到一个应用程序上下文包含的bean名称以一行逗号列出。您可以在日志中发现这两个应用程序上下文,并查找创建的bean。如果您在这两个上下文中看到定义了相同的控制器,那么您知道您的应用程序遇到了问题。实际上,您不需要调试,信息就足够了。这里有一个例子:
在o中预实例化单例