Gamze Çalışkan
Gamze Çalışkan

Reputation: 23

Cannot update after a successfull save

I'm relatively new at Spring MVC. In my uploadPub.java file dService.saveDocument(doc); method runs successfully. I call it to get an Id for the record. Then i want to update the same record with new values. Fails to do though. No error message or exception. I'm on Spring 4.0.5 and hibernate 4.3.5. Here are the files. Thanks for the help.

uploadPub.java

    public int uploadPub(MultipartFile filea) { 
    String originalName = null;
    String path = null;
    Documents doc = new Documents("", "", 'N', DateUtils.getNow());

    int docId = dService.saveDocument(doc);

    try {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        if (filea != null && filea.getSize() > 0) {
            File targetFile = new File("C:\\yayinDoc");
            if (!targetFile.exists()) {
                targetFile.mkdir();
            }
            originalName = filea.getOriginalFilename();
            String extension = FilenameUtils.getExtension(originalName);
            if (extension.equals("doc") || extension.equals("docx")) {
                path = targetFile.getPath() + "\\" + docId + "." + extension;
                inputStream = filea.getInputStream();
                outputStream = new FileOutputStream(path);

                int readBytes = 0;
                byte[] buffer = new byte[8192];
                while ((readBytes = inputStream.read(buffer, 0, 8192)) != -1) {
                    outputStream.write(buffer, 0, readBytes);
                }
                outputStream.close();
                inputStream.close();

                Documents docUpdate = new Documents(docId, originalName, path, 'Y', DateUtils.getNow());

                dService.updateDocument(docUpdate);

                return docId;
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return 0;
}

DocumentsService.java

@Transactional
@Service("documentsService")
public class DocumentsService extends GenericManagerImp<Documents> {

@Autowired
private DocumentsDao documentsDao;

public DocumentsService() {
    super();
}

public DocumentsService(DocumentsDao documentsDao) {
    this.documentsDao = documentsDao;
}


public int saveDocument(Documents doc) {
    documentsDao.saveDocument(doc);
    return doc.getDocId();
}


public void updateDocument(Documents doc) {
    documentsDao.updateDocument(doc);
}


public void deleteDocument(Documents doc) {
    documentsDao.deleteDocument(doc);
}

}

DocumentsDao.java

@Repository("documentsDAO")
public class DocumentsDao extends GenericDaoImp<Documents> {

public DocumentsDao() {
    super(Documents.class);
    this.sessionFactory = HibernateUtil.getSessionFactory();

}


public void saveDocument(Documents documents) {
    save(documents);
}


public void updateDocument(Documents doc) {
    update(doc);
}


public void deleteDocument(Documents doc) {
    delete(doc);
}
}

GenericDaoImp.java

public class GenericDaoImp<T> implements GenericDao<T> {

private Class<T> persistentClass;

protected SessionFactory sessionFactory;



public GenericDaoImp(final Class<T> persistentClass) {
    this.persistentClass = persistentClass;
    this.sessionFactory = HibernateUtil.getSessionFactory();
}

public GenericDaoImp(final Class<T> persistentClass, SessionFactory sessionFactory) {
    this.persistentClass = persistentClass;
    this.sessionFactory = sessionFactory;
}

public SessionFactory getSessionFactory() {
    return this.sessionFactory;
}

public Session getSession() {
    Session currentSession = getSessionFactory().openSession();

    return currentSession;
}

public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}


public T save(T object) {
    getSession().save(object);
    return object;
}

public T persist(T object) {
    getSession().persist(object);
    return object;
}

public T update(T object) {
    getSession().update(object);
    return object;
}


public void delete(T object) {
    getSession().delete(object);
}
}

dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">


<!-- Enables the Spring MVC @Controller programming model -->
<tx:annotation-driven transaction-manager="hibernateTransactionManager"  proxy-target-class="true"/>
<mvc:annotation-driven />

<context:annotation-config />
<context:component-scan base-package="com.pub.controller" />
<context:component-scan base-package="com.pub.service" />
<context:component-scan base-package="com.pub.dao" />
<context:component-scan base-package="com.pub.model" />


<bean id="hibernateTransactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
   <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://xxx"></property>
    <property name="username" value="xxx"></property>
    <property name="password" value="xxx"></property>
</bean>

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource" />
    <property name="hibernateProperties">
    <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>

</bean>

<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView" />
    <property name="order" value="2" />
    <property name="prefix">
        <value>/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

<bean id="tilesConfigurer"
    class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/tiles.xml</value>
        </list>
    </property>
</bean>

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="order" value="1" />
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>

<mvc:default-servlet-handler />

Upvotes: 0

Views: 115

Answers (2)

Gamze &#199;alışkan
Gamze &#199;alışkan

Reputation: 23

Thank you for your responses. I should use same object for both save and update. So I saved object and change the same object retrieving from db and update it. I used merge instead of update. Thanks again. Working code:

public int uploadPub(MultipartFile filea, String ipAddress) {
    String originalName = null;
    String path = null;
    Documents doc = new Documents("eser", "eser", 'N', DateUtils.getNow());
    Documents docUpdate = dService.saveDocument(doc);

    try {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        if (filea != null && filea.getSize() > 0) {
            File targetFile = new File("C:\\PubFolder");
            if (!targetFile.exists()) {
                targetFile.mkdir();
            }
            originalName = filea.getOriginalFilename();
            String extension = FilenameUtils.getExtension(originalName);
            if (extension.equals("pdf")) {
                path = targetFile.getPath() + "\\" + docUpdate.getDocId() + "." + extension;
                inputStream = filea.getInputStream();
                outputStream = new FileOutputStream(path);

                int readBytes = 0;
                byte[] buffer = new byte[8192];
                while ((readBytes = inputStream.read(buffer, 0, 8192)) != -1) {
                    outputStream.write(buffer, 0, readBytes);
                }
                docUpdate.setActive('Y');
                docUpdate.setUploadDate(DateUtils.getNow());

                dService.mergeDocument(docUpdate);
                outputStream.close();
                inputStream.close();
                return docUpdate.getDocId();
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return 0;

Upvotes: 0

Petar Butkovic
Petar Butkovic

Reputation: 1910

Read about hibernate object states.

Problem is that you are using update but your object is detached. You can solve it in two ways;

  • Use mergemethod for updating your newly created document

    Read about your use case and using of the merge(This article)

  • Use the same session, you are always creating a new one. So instead this,

    Session currentSession = getSessionFactory().openSession();

    use something like this,

    Session currentSession = getSessionFactory().getCurrentSession();

UPDATE

Try to update your GenericDaoImpl class

public T update(T object) {
    Session session = getSession();
    session.update(object);
    session.flush();
    return object;
}

Hope it helps

Upvotes: 1

Related Questions