简体   繁体   English

Spring Data JPA:在save()方法之后获取实体中的数据

[英]Spring Data JPA: Fetching data from entity just after save() method

I'm using Spring Data JPA with Hibernate JPA provider in my project. 我在我的项目中使用Spring Data JPA和Hibernate JPA提供程序。 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. 在日志中,我只看到insert语句,没有select的详细信息。

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数据jpa方法 - getOne(id),但它也不起作用(insert语句调用,select not);

UPDATE: I removed @Transactional annotaion from my service and from test. 更新:我从我的服务和测试中删除了@Transactional annotaion。 Now when I'm saving an entity and then fetching the same entity, I have two sql statements in logs: insert and then select. 现在当我保存一个实体然后获取同一个实体时,我在日志中有两个sql语句:insert然后选择。 Maybe my problem is because of wrong persistence/transaction configuration. 也许我的问题是由于错误的持久性/事务配置。 What You think? 你认为呢?

这可能有点过时,但我遇到了同样的问题,发现hibernate二级缓存是个问题。

The save() method may or may not write your changes to database immediately. save()方法可能会也可能不会立即将更改写入数据库。 If you want to commit the changes immediately, you will need to use T saveAndFlush(T entity) method. 如果要立即提交更改,则需要使用T saveAndFlush(T entity)方法。

The print statement is returning null because, only the getName() returns null. print语句返回null,因为只有getName()返回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. 如果“saved”对象为null,则应该抛出空指针异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM