当前位置: 首页 > 面试题库 >

将实体保存在资源库中不起作用SPRING

宣望
2023-03-14
问题内容

我正在尝试将实体保存在存储库中,但它根本不起作用。存储库是自动连线的,在运行时中,我使用saveAndFlush来保存实体。我正在使用PostgreSQL。在测试方法上方,我添加了注释并解释了发生的情况。我希望该方法saveAndFlush应该可以,但不能。我找不到原因。

@Transactional
public class TestClass{

    @Autowired private MyRepository repository;
    @Autowired private EntityManager entityManager;

    // Working version
    public void writingToRepositoryWorking() {
        entityManager.getTransaction().begin();
        entityManager.persist(new MyData(99));
        entityManager.getTransaction().commit();

    }

    // not working and throws exception : 
    // TransactionRequiredException: no transaction is in progress
    public void writingToRepositoryNotWorking() {
        repository.saveAndFlush(new MyData(99));
    }

    // not working, no exception, no data in repository, 
    // but auto generated ID is incremented
    public void writingToRepositoryNotWorkingToo() {
        repository.save(new MyData(99));
    }
}

存储库接口文件

@Repository
@Transactional
public interface MyRepository extends JpaRepository<MyData, Long> {}

MyData文件

@Entity(name = "myData")
public class MyData {
    @Id @GeneratedValue(strategy = GenerationType.AUTO) long id;

    private int testValue;

    public MyData() { }

    public BugData(int testValue) {
        this.testValue = testValue;
    }

    public long getId() {
        return id;
    }

    public int getTestValue() {
        return testValue;
    }
}

ApplicationConfiguration文件

@Configuration
@EnableJpaRepositories("com.mypackage.app")
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
@EnableWebMvc
class ApplicationConfiguration extends WebMvcConfigurationSupport {

    @Value("${jdbc.url}") private String KEY_JDBC_URL;

    @Value("${jdbc.username}") private String KEY_JDBC_USERNAME;

    @Value("${jdbc.password}") private String KEY_JDBC_PASSWORD;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    @Autowired
    public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
        LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setPackagesToScan("com.mypackage.app");
        factory.setHibernateProperties(hibernateProperties());
        return factory;
    }

    public Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        return properties;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
        return new HibernateTransactionManager(sessionFactory);
    }

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl(KEY_JDBC_URL);
        dataSource.setUsername(KEY_JDBC_USERNAME);
        dataSource.setPassword(KEY_JDBC_PASSWORD);
        return dataSource;
    }

    @Bean
    public EntityManagerFactory  entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();

        em.setDataSource(dataSource());
        em.setPackagesToScan("com.mypackage.app");
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        em.setJpaProperties(hibernateProperties());
        em.afterPropertiesSet();

        return em.getObject();
    }

    @Bean
    public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
        return entityManagerFactory.createEntityManager();
    }

    ...
}

问题答案:

对于初学者,您实际上EntityManager在不工作的测试用例中使用两种不同的方法:

  1. EntityManager 通过Spring自动连接到您的测试中(这是单例,无论如何都应避免使用),其他是
  2. EntityManagerEntityManagerFactory您的ApplicationConfiguration中的配置创建。

同时,EntityManagers由于Hibernate的配置,您还将在上述2旁边运行另一个Session
SessionFactory。另外,由于配置了HibernateTransactionManager,所有由创建的事务@Transactional都绑定到由存储库创建SessionFactoryEntityManager使用的Hibernate会话,因此肯定无法了解它。这就是为什么TransactionRequiredException在您的存储库尝试保留数据时引发的原因。

要解决此问题,
您可以考虑删除HibernateSessionFactory,并将事务管理器切换为JpaTransactionManager。然后,@Transactional在您的存储库上将具有创建新事务并将其绑定EntityManager到Spring已知的现有事务的作用。

值得一提的是,@Transactional您的TestClass上的完全没有帮助,因为此类的实例没有由Spring实例化和管理。为了使这项工作有效,需要按如下所述提供正确的事务测试类配置:http :
//docs.spring.io/spring/docs/current/spring-framework-
reference/html/testing.html。

希望这可以帮助。



 类似资料:
  • 我试图在构建时使用maven资源插件复制xml文件,但到目前为止没有成功。 Maven目标-干净安装 它需要任何特殊的maven目标来复制东西吗?请帮帮我。 插件版本 提到这个

  • 我创造了一个实体。我想写一个RestController来在MySQL中保存这个实体和一个图像。我使用了Java8、SpringBoot、Hibernate、Rest API、JSON。我该怎么做呢?我可以一起保存吗? 控制器

  • 我在使用JPA时遇到了一些困难。我没有得到任何异常,但我不能保存任何东西到数据库。我从Hibernate到Jpa,在那里一切都工作得很好。下面是我的文件 Application.Properties: 存储库: 服务: 我在提交表单时得到了200的响应,但在数据库中找不到数据

  • 我在尝试用@Inject搭配JAX-RS。我的问题是@Inject只在Servlets中有效。在JAX资源中,我得到一个空指针,我不知道我做错了什么。我的代码如下所示: Pom.xml文件 豆类.xml 网页.xml包含: <代码> 工人阶级: 服务控制器。startTweetListener()和serviceController。stopTweetListener()工作。没有空指针。 非工人

  • 我正在尝试开发一个小型电子商务项目。我有一个篮子和篮子项目实体。我只是想当我为客户保存购物篮时,我想把购物篮项目保存在数据库中。我认为我不应该为篮子项目创建存储库。我应该能够保存篮子项目,同时使用篮子存储库保存篮子。 在这里,我试图通过篮子服务获得一个篮子项目,并将其设置为篮子实体并保存它。 我有什么问题?我有个例外。

  • 这根本不是关于Spring靴的。 我的英语可以更好。 使用下面的Spring Data配置,我正在尝试执行DML请求。 恰好是< code>CrudRepository#save方法。 然而,执行Spring的CrudRepository#保存方法,我接下来要做的是: 只有选择由功能记录。 没有执行任何“插入”或“更新”语句来hibernate.show_sql日志记录。 数据库根本没有变化。 =