Reputation: 849
My entityManager persist() gets id from sequence and puts it to my Image object but the Image object itself is not showing up in the database. EntityManager.flush() gives an error so I can't commit this way. Here is my code.
@Repository
public class ImageDaoImpl extends BaseDao implements ImageDao {
@PersistenceContext
protected EntityManager entityManager;
@Override
@Transactional
public void create(Image image) {
JpaTemplate jpaTemplate = getJpaTemplate(entityManager);
jpaTemplate.persist(image);
}
@Repository
public class BaseDao {
private JpaTemplate jpaTemplate;
public JpaTemplate getJpaTemplate(EntityManager entityManager){
if(jpaTemplate == null)
jpaTemplate = new JpaTemplate(entityManager);
return jpaTemplate;
}
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
</bean>
</property>
<property name="persistenceUnitName" value="sample"></property>
</bean>
<!-- DataSource Setup -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/imageCapture" />
<property name="username" value="myusername" />
<property name="password" value="mypassword" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
Upvotes: 30
Views: 91719
Reputation: 31
Check EntityManager object is not getting created twice. In my case I was initialize EntityManager object in one method and mistakenly calling that method twice during opening transaction and persisting data.
Incorrect code:
EntityTrasaction transaction = getEntityManager().getTransaction().begin();
getEntityManager().persist(customer); // This line is calling another object of EntityManager
transaction.commit();
Correct code:
EntityManager em = getEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(customer);
transaction.commit();
public EntityManager getEntityManager(){
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("punit");
return entityManagerFactory.createEntityManager();
}
Upvotes: 3
Reputation: 1085
Check your server logs. Are you creating new EntityManger
? and have not begun the transaction. I think, Where you have begun that is another EntityManager
object.
Upvotes: 2
Reputation: 15327
I faced this problem in when running test cases with SpringJUnit4ClassRunner
I solved it by wrapping the test function with
@Autowired
private PlatformTransactionManager transactionManager;
// in your test funciton
// Declare a transaction programmatically to be able to rollback.
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
try {
// here test of Dao goes
} finally {
transactionManager.rollback(transaction);
}
hope this helps you
Upvotes: 0
Reputation: 2874
persist()
means "add object to list of managed entries". To save object to data base you must call flush()
method. But remember you must call in inside the transaction.
//Edit: Example save method.
public void save(T t){
// begin transaction
em.getTransaction().begin();
if (!em.contains(t)) {
// persist object - add to entity manager
em.persist(t);
// flush em - save to DB
em.flush();
}
// commit transaction at all
em.getTransaction().commit();
}
This is not the best that you can make, but good enough.
Upvotes: 32
Reputation: 1
Check your mvc-dispatcher-servlet.xml
. Here in <context:component-scan base-package="pass"/>
pass should equal to package where your controllers are
Upvotes: 0
Reputation: 7902
This generally happens when Transaction in not applied.. I doubt @Transactional interceptor is not intercepting properly.
Upvotes: 32