Spring Data JPA: fetching data from object right after save () method

I am using Spring Data JPA with Hibernate JPA provider in my project. Inside my service, I have a method that stores an object in the database and then uses the returned object. I am trying to get more details about this object. As a result, the parts are not retrieved. In the logs I only see insert statement, no selection for details.

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();
  }
}

      

Services:

@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 the last few lines of the logs:

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 method jpa - getOne (id) after save (), but also it doesn't work (insert statement, invoke, don't select);

UPDATE: I removed @Transactional annotaion from my service and from test. Now when I save the object and then get the same object, I have two sql statements in the logs: insert and then select. Perhaps my problem is related to a persistent / transaction misconfiguration. What do you think?

+5


source to share


3 answers


This might be a little out of date, but I ran into the same problem and found the problem was in the hibernation level 2 cache.



+2


source


The save () method may or may not immediately write your changes to the database. If you want to commit changes immediately, you will need to use the T saveAndFlush(T entity)

.



+1


source


The print statement returns null because only getName () returns null. This means your data is saved and the object is returned back. If the "stored" object was null, it should have thrown a null pointer exception.

-1


source







All Articles