gpt4 book ai didi

mysql - 使用 CrudRepository 持久化 JPA 实体

转载 作者:行者123 更新时间:2023-11-29 12:52:52 25 4
gpt4 key购买 nike

通过 CrudRepository 保存 JPA 实体时遇到问题。它似乎返回传递给它的原始对象,而不将对象持久化到数据库。我知道这不是正确的方法,但出于测试目的,如果我在保存之前放置 TransactionSynchronizationManager 的实例,它似乎会正确持久。这让我想到事务管理器可能存在问题?

此外,如果我放弃存储库并使用实体管理器 (em),我会得到相同的结果,但是如果我调用 em.flush(),我会得到异常“Transactionrequiredception,没有正在进行的事务”。

@Transactional
public class UserServiceImpl implements UserService{

@Autowired
private UserRepository userRepository;

@Autowired
private EntityManagerFactory emf;

@Override
@Transactional(readOnly=false)
public User save(User user) {

// EntityManager em = emf.createEntityManager();
//Object persists when adding following line
// TransactionSynchronizationManager.bindResource(emf , new EntityManagerHolder(em));
return userRepository.save(user);
}

}


@ComponentScan(basePackages = {"..."})
@Import(value={DataContextConfig.class,SecurityConfig.class})
public class AppConfig{
}

@Configuration
@ComponentScan(basePackages = {".."})
@Import(DataConfig.class)
public class DataContextConfig {

}

@Configuration
@EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
@EnableJpaRepositories(value={"com.repository"}, entityManagerFactoryRef="entityManagerFactory", transactionManagerRef="transactionManager")
@PropertySource("classpath:data.properties")
public class DataConfig {
...
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory((EntityManagerFactory) entityManagerFactory());
return txManager;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factory.setPackagesToScan("...");
factory.setJpaPropertyMap(jpaProperties());
factory.setDataSource(dbSource());
return factory;
}


@Bean
public DriverManagerDataSource dbSource(){
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
driverManagerDataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
driverManagerDataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
driverManagerDataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return driverManagerDataSource;
}

}

我上传了一个隔离异常的小项目。压缩并运行 AccountTester.class http://www14.zippyshare.com/v/81636273/file.html

最佳答案

根据您的示例项目。以下是为避免 TransactionRequiredException: no transaction is in Progress 问题并成功插入帐户而修改的唯一类:

package com.jpa.base.repository;

import com.jpa.base.entity.Account;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {

public Account findByEmailAddress(@Param(value = "emailAddress") String emailAddress);

public Account findByAccountId(@Param(value = "accountId") Long accountId);

}

Original for reference

您需要使用 @Repository 标记您的 Spring Data JPA 存储库(不是您的服务)。 See here

package com.jpa.base.service.impl;

import com.jpa.base.entity.Account;
import com.jpa.base.repository.AccountRepository;
import com.jpa.base.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("accountService")
public class AccountServiceImpl implements AccountService {

@Autowired
private AccountRepository accountRepository;

@Override
@Transactional(readOnly = true)
public Account findByAccountId(Long accountId) {
return accountRepository.findByAccountId(accountId);
}

@Override
@Transactional(readOnly = true)
public Account findByEmailAddress(String emailAddress) {
return accountRepository.findByEmailAddress(emailAddress);
}

@Override
@Transactional
public Account save(Account account) {
return accountRepository.save(account);
}

}

Original for reference

请注意从服务中删除 @Repository 的更改(需要位于 Spring Data JPA 存储库接口(interface)上)并使用 accountRepository 将实体保留在 保存(...)方法。

不知道为什么您尝试使用 EntityManagerFactory 创建一个新的 EntityManager (如果您确实需要一个 EntityManager 实例,您应该注入(inject)配置的 EntityManager,而不是工厂)。这也恰好是您的 TransactionRequiredException 的原因。

总之,当您可以使用存储库来持久化实体时,为什么还要费心这些呢?运行您的 AccountTester 现在会产生所需的功能:

...
Hibernate: insert into account (email_address, name, version) values (?, ?, ?)
INFO : com.jpa.base.entity.AccountTester - Account Saved: Account Id: 3, Email Address:james.brown@outlook.com, Name: James Brown, Version: 0

关于mysql - 使用 CrudRepository 持久化 JPA 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24469690/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com