Java SpringDataJPA:在save()方法之后从实体获取数据
我在项目中使用SpringDataJPA和HibernateJPA提供程序。 在我的服务中,我有一个方法,它将一个实体保存在数据库中,而不是使用返回的对象,我尝试获取有关该实体的更多详细信息。 因此,无法获取详细信息。在日志中,我只看到insert语句,没有select作为详细信息 这是我的密码: 配置:Java SpringDataJPA:在save()方法之后从实体获取数据,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,我在项目中使用SpringDataJPA和HibernateJPA提供程序。 在我的服务中,我有一个方法,它将一个实体保存在数据库中,而不是使用返回的对象,我尝试获取有关该实体的更多详细信息。 因此,无法获取详细信息。在日志中,我只看到insert语句,没有select作为详细信息 这是我的密码: 配置: @Configuration @Profile("test") @EnableJpaRepositories(basePackages = {"pl.lodz.uml.sonda.common
@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
@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;
}
}
简单测试:
@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());
}
}
实体:
@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 ...
我还尝试在save()之后运行SpringDataJPA方法-getOne(id),但它也不起作用(调用了insert语句,选择not)
更新:
我从服务和测试中删除了@Transactional注释。现在,当我保存一个实体,然后获取同一个实体时,我在日志中有两条sql语句:insert和select。
可能我的问题是因为错误的持久性/事务配置。您的想法是什么?save()方法可能会也可能不会立即将您的更改写入数据库。如果要立即提交更改,则需要使用
T saveAndFlush(T entity)
方法。print语句返回null,因为只有getName()返回null。
这意味着您的数据将被保存,对象将被返回。如果“保存的”对象为空,它应该抛出空指针异常。这可能有点过时,但我遇到了相同的问题,发现hibernate二级缓存是问题所在。仍然无法工作。当我询问实体详细信息时,我得到了null。当我尝试在save()之后执行findOne(id)方法时,然后在日志中,我只看到insert语句而没有select。是的,我知道如何从我的服务方法
saveProbe(Probe Probe)
获取此数据:saved.getGroup().getName()。正如您在测试方法中所看到的,我在保存之前填写了所有必要的数据。@bhop“正如您所看到的…”-不,我们不能。我们所能看到的就是你调用了一些方法。我们不知道他们到底在做什么。因此,我们也看不到实体。很抱歉:)。现在您可以真正看到我的实体了,我遇到了一个类似的问题:我的事务日志是通过触发器更新的,日志条目是建模的实体,但是在saveAndFlush()之后不会加载关系,因此我必须传递ID并进行提取,就好像我还没有对象一样。第一:不要在Spring(数据)测试中使用事务性注释。Spring为您创建一个事务并回滚该事务。第二:提交后会出现物理刷新。使用Transactional注释的方法将在离开方法后提交(如果此方法未引发异常)。请在下面写下如何解决此问题。
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