0

My model is

import javax.annotation.Nonnull;
import javax.persistence.Entity;
import org.joda.time.DateTime;
@Entity
public class Network extends AbstractEntity {
 private long networkId;
 private String name;
 private boolean active;
 private DateTime createdAt;
 private String createdBy;
 private DateTime updatedAt;
 private String updatedBy;
 ...
}

AbstractEntity is

@MappedSuperclass
public class AbstractEntity {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Long id;
 public Long getId() {
 return id;
 }
 @Override
 public boolean equals(final Object obj) {
 if (this == obj) {
 return true;
 }
 if (obj == null || getClass() != obj.getClass()) {
 return false;
 }
 final AbstractEntity abstractEntity = (AbstractEntity) obj;
 return id.equals(abstractEntity.id);
 }
 @Override
 public int hashCode() {
 return id == null ? 0 : id.hashCode();
 }
}

I have Repository where I want to add entity. I do

@Repository
public class NetworkRepositoryImpl implements NetworkRepository {
 @PersistenceContext
 private EntityManager entityManager;
 @Override
 @Nonnull
 public List<Network> findAll() {
 //noinspection JpaQlInspection
 final Query query = entityManager.createQuery("SELECT e FROM Network e");
 return (List<Network>)query.getResultList();
 }
 @Nonnull
 @Override
 @Transactional
 public Network save(@Nonnull final Network network) {
 if (network.getId() == null) {
 entityManager.persist(network);
 return network;
 } else {
 return entityManager.merge(network);
 }
 }
}

and I Test it as

@Test
public void testAllNetworks() {
 final Network network = new Network(1, "US", true, DateTime.now());
 final Network networkInDb = networkRepository.save(network);
 assertNotNull(networkInDb.getId());
 final List<Network> networks = networkRepository.findAll();
 assertTrue(networks.isEmpty());
}

my ApplicationConfig looks like

@Configuration
@ComponentScan
@EnableJpaRepositories
public class ApplicationConfig {
 @Bean
 public DataSource dataSource() {
 final EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder();
 embeddedDatabaseBuilder.setType(EmbeddedDatabaseType.H2);
 return embeddedDatabaseBuilder.build();
 }
 @Bean
 public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
 final HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
 jpaVendorAdapter.setDatabase(Database.H2);
 jpaVendorAdapter.setGenerateDdl(true);
 final LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
 localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
 localContainerEntityManagerFactoryBean.setPackagesToScan("com.org.comma.persistence");
 localContainerEntityManagerFactoryBean.setDataSource(dataSource());
 localContainerEntityManagerFactoryBean.setPersistenceUnitName("test-comma-pu");
 return localContainerEntityManagerFactoryBean;
 }
 @Bean
 public PlatformTransactionManager transactionManager() {
 final JpaTransactionManager transactionManager = new JpaTransactionManager();
 transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
 return transactionManager;
 }
}

My test fails on line

 assertNotNull(networkInDb.getId());

meaning the entity is not persisted

What I am doing wrong here?

asked May 23, 2014 at 3:37

2 Answers 2

1

In my case, I was using wrong annotation.

I was using

import javax.transaction.Transactional;

instead, what I needed was

import org.springframework.transaction.annotation.Transactional;

Atleast I see it try persisting and failing somewhere else

answered May 23, 2014 at 5:32
Sign up to request clarification or add additional context in comments.

2 Comments

:) happens to all of us. Fyi if you use STS an orange semi-circular arrow should appear if the @Transactional is effecive: i.imgur.com/WZ2cFFD.png
Thanks @gerrytan, I use IntelliJ IDEA
0

If your test fails because Id value is null, then it is expected behavior.

When hibernate persist an entity, it will not fetch the auto-generated key value automatically. You should either find the entity again or refresh it manually.

In similar situation, I usually refresh the entity like below.

entityManager.persist(network);
entityManager.flush();
entityManager.refresh(network);

P.S: You should flush before refreshing to make it reliable.

answered May 23, 2014 at 4:15

2 Comments

I don't think so, his repository method had @Transactional so that should automatically flush at the end of invocation
Yes, it will flush at the end of the transaction. But if you want the auto-generated value to be fetched before end-of-transaction, then you would need to flush and refresh the entity. By default, hibernate will not fetch auto-generated key value when persisting an entity.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.