java Spring Data JPA:在 save() 方法之后从实体中获取数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25462416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Data JPA: Fetching data from entity just after save() method
提问by bhop
I'm using Spring Data JPA with Hibernate JPA provider in my project. Inside my service I have a method, which saves an entity in database and than using returned object I try to fetch more details about this entity. As a result, details are not fetched. In logs I see only insert statement, without select for details.
我在我的项目中使用 Spring Data JPA 和 Hibernate JPA 提供程序。在我的服务中,我有一个方法,它在数据库中保存一个实体,而不是使用返回的对象,我尝试获取有关该实体的更多详细信息。因此,不会获取详细信息。在日志中,我只看到插入语句,没有选择详细信息。
Here is my code:
这是我的代码:
Configuration:
配置:
@Configuration
@Profile("test")
@EnableJpaRepositories(basePackages = {"pl.lodz.uml.sonda.common.repositories"})
@EnableTransactionManagement
@PropertySource(value = "classpath:db.test.properties")
public class PersistenceConfigTest {
@Autowired
private Environment env;
@Value("classpath:sql/test-initialization.sql")
private Resource sqlInitializationScript;
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.username"));
dataSource.setPassword(env.getProperty("jdbc.password"));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(env.getProperty("hibernate.showSQL", Boolean.class));
adapter.setGenerateDdl(env.getProperty("hibernate.hbm2ddl", Boolean.class));
entityManagerFactory.setDataSource(dataSource());
entityManagerFactory.setPackagesToScan("pl.lodz.uml.sonda.common.domains");
entityManagerFactory.setJpaVendorAdapter(adapter);
Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
entityManagerFactory.setJpaProperties(properties);
return entityManagerFactory;
}
@Bean(name = "transactionManager")
public PlatformTransactionManager platformTransactionManager() {
EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject();
return new JpaTransactionManager(entityManagerFactory);
}
@Bean
public DataSourceInitializer dataSourceInitializer() {
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(sqlInitializationScript);
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource());
initializer.setDatabasePopulator(populator);
initializer.setEnabled(env.getProperty("db.initialization", Boolean.class));
return initializer;
}
@Bean
public ProbeService probeService() {
return new ProbeServiceImpl();
}
}
Service:
服务:
@Service
@Transactional
public class ProbeServiceImpl implements ProbeService {
@Autowired
private ProbeRepository probeRepository;
@Override
public Probe saveProbe(Probe probe) {
Probe saved = probeRepository.save(probe);
saved.getGroup().getName();
return saved;
}
}
Simple test:
简单测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {PersistenceConfigTest.class})
@Transactional
@TransactionConfiguration(defaultRollback = true)
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class
})
public class ProbeServiceImplTest {
@Autowired
private ProbeService probeService;
@Test
public void test() {
Probe probe = ProbeFixtures.generateProbeSample("Test one");
probe.setGroup(ProbeFixtures.generateProbeGroupSample(1));
Probe saved = probeService.saveProbe(probe);
System.out.println("Group name: " + saved.getGroup().getName());
}
}
Entities:
实体:
@Entity
@Table(name = "probes")
public class Probe {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "probe_id")
private long probeId;
@Column(name = "probe_title", nullable = false)
private String title;
@Column(name = "probe_description", nullable = true)
private String description;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "probe_group_id", nullable = true)
private ProbeGroup group;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "probe_image_id", nullable = true)
private ProbeFile image;
@Column(name = "probe_published_date", nullable = false)
private Date published;
@Column(name = "probe_last_updated_date", nullable = false)
private Date updated;
@Column(name = "probe_expire_date", nullable = false)
private Date expires;
@Column(name = "probe_is_active", nullable = false)
private boolean isActive;
@OneToMany(mappedBy = "probe", fetch = FetchType.LAZY)
private List<Question> questions;
@OneToMany(mappedBy = "probe", fetch = FetchType.LAZY)
private List<Vote> votes;
public Probe() {
questions = new LinkedList<>();
votes = new LinkedList<>();
}
// getters & setters ...
@Entity
@Table(name = "probe_groups")
public class ProbeGroup {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "probe_group_id")
private long probeGroupId;
@Column(name = "probe_group_name", nullable = false, unique = true)
private String name;
@Column(name = "probe_group_description", nullable = true)
private String description;
@OneToMany(mappedBy = "group", fetch = FetchType.LAZY)
private List<Probe> probes;
public ProbeGroup() {
probes = new LinkedList<>();
}
// getters & setters ...
And few last logs lines:
最后几行日志:
Hibernate: insert into probes (probe_description, probe_expire_date, probe_group_id, probe_image_id, probe_is_active, probe_published_date, probe_title, probe_last_updated_date) values (?, ?, ?, ?, ?, ?, ?, ?)
Group name: null
I also tried to run spring data jpa method - getOne(id) after save(), but also it does not work (insert statement invoked, select not);
我还尝试在 save() 之后运行 spring data jpa 方法 - getOne(id),但它也不起作用(调用了插入语句,不选择);
UPDATE:I removed @Transactional annotaion from my service and from test. Now when I'm saving an entity and then fetching the same entity, I have two sql statements in logs: insert and then select. Maybe my problem is because of wrong persistence/transaction configuration. What You think?
更新:我从我的服务和测试中删除了 @Transactional annotaion。现在,当我保存一个实体然后获取同一个实体时,我在日志中有两个 sql 语句:插入然后选择。也许我的问题是因为错误的持久性/事务配置。你认为呢?
回答by Ratshi?aho Wayne
This might be a bit outdated, but I ran into the same issue and found that hibernate 2nd level cache was the issue.
这可能有点过时,但我遇到了同样的问题,发现休眠二级缓存是问题所在。
回答by Naresh Vavilala
The save() method may or may not write your changes to database immediately. If you want to commit the changes immediately, you will need to use T saveAndFlush(T entity)
method.
save() 方法可能会也可能不会立即将您的更改写入数据库。如果要立即提交更改,则需要使用T saveAndFlush(T entity)
方法。
回答by Benoy Prakash
The print statement is returning null because, only the getName() returns null. That means your data is getting saved, and the object is returned back. If the "saved" object was null, it should have thrown a null pointer exception.
打印语句返回空值,因为只有 getName() 返回空值。这意味着您的数据正在被保存,并且对象被返回。如果“已保存”对象为空,则它应该抛出空指针异常。