document not saving in spring jpa document manager application

前端 未结 4 2002
情歌与酒
情歌与酒 2020-12-10 13:38

I am developing a document management application in spring using jpa and MySQL. The application is currently accepting a document an

4条回答
  •  庸人自扰
    2020-12-10 14:42

    Your JPA mappings seem good. Obviously, @Lob requires data type to be byte[] / Byte[] / or java.sql.Blob. Based on that, plus your symptoms and debugging printout it seems your code doing the correct data manipulation (JPA annotations good), but the combination of spring + MySQL isn't commiting. This suggests a minor problem with your spring transactional config OR with your MySQL data type.

    1. Transactional Behaviour

    The relevant code in JpaDocumentRepository.java is:

    @PersistenceContext
    private EntityManager em;
    
    @Override
    public void save(Document document) {
        if (document.getId() == null) {this.em.persist(document);}
        else {this.em.merge(document);}
    }  
    
    • You're not using EJBs (hence no 'automatic' container-managed transactions).
    • You're using JPA within Servlets/java classes (hence you require 'manual' transaction demarcation - outside servlet container; in your code or via Spring config).
    • You are injecting the entity manager via @PersistenceContext (i.e. container-managed entity manager backed by JTA, not a Entity Manager resource-local transaction, em.getTransaction())
    • You have marked your 'parent' method as @Transactional (i.e. spring proprietary transcations - annotation later standardised in Java EE 7).

    The annotations and code should give transactional behaviour. Do you have a Spring correctly configured for JTA transactions? (Using JtaTransactionManager, not DataSourceTransactionManager which gives JDBC driver local transactions) Spring XML should contain something very similar to:

    
     
    
    
    
    
    
    
      
        
    
    

    Be suspicious of additional parameters / settings.

    This is the manually coded version of what Spring must do (for understanding only - don't code this). Uses UserTransaction (JTA), not em.getTransaction() of type EntityTransaction (JDBC local):

    // inject a reference to the servlet container JTA tx
    @Resource UserTransaction jtaTx;
    
    // servlet container-managed EM
    @PersistenceContext private EntityManager em; 
    
    public void save(Document document) {
        try {
            jtaTx.begin();
            try {
                if (document.getId() == null) {this.em.persist(document);}
                else {this.em.merge(document);}
                jtaTx.commit();
            } catch (Exception e) {
                 jtaTx.rollback();
                 // do some error reporting / throw exception ...
            }
        } catch (Exception e) {
            // system error - handle exceptions from UserTransaction methods
            // ...
        }
    }
    

    2. MySQL Data Type

    As shown here (at bottom), MySql Blobs are a bit special compared to other databases. The various Blobs and their maximum storage capacities are:

    TINYBLOB - 255 bytes BLOB - 65535 bytes MEDIUMBLOB - 16,777,215 bytes (2^24 - 1) LONGBLOB - 4G bytes (2^32 – 1)

    If (2) turns out to be your problem:

    • increase the MySQL type to MEDIUMBLOB or LONGBLOB
    • investigate why you didn't see an error message (v important). Was your logging properly configured? Did you check logs?

提交回复
热议问题