ivar
ivar

Reputation: 849

EntityManager persist() not saving anything to database

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

Answers (6)

Rahul
Rahul

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

Atul Jain
Atul Jain

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

Basheer AL-MOMANI
Basheer AL-MOMANI

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

Koziołek
Koziołek

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

zafezo
zafezo

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

Premraj
Premraj

Reputation: 7902

This generally happens when Transaction in not applied.. I doubt @Transactional interceptor is not intercepting properly.

Upvotes: 32

Related Questions