0

I have the following class:

class Exibitions {

    String name
    String location
    String description
    Date dateStart
    Date dateEnd


    byte[] flier

    static mapping = {
        flier sqlType:'longblob'      //use mysql
    }

    static constraints = {
        description nullable: true
        flier nullable: true
    }
}

The admin can upload the flier (a PDF file) with this form:

<g:if test="${exibitionInstance?.flier}">
    Inserted
</g:if><g:else>
    <g:form action="uploadFlier" id="${exibitionInstance.ident()}" enctype="multipart/form-data">
       Insert Flier (PDF):
       <input type="file" id="flier" name="flier" />
       <g:actionSubmit class="create" action="uploadFlier" value="Carica"  />
    </g:form>
</g:else>

The controller code handling the upload is the following:

def uploadFlier(){
    Exibition exibitionInstance = Exibition.get(params.id)
    def file = request.getFile('flier')
    if(file.empty) {
        flash.message = "File cannot be empty"
    } else {

        exibitionInstance.flier = file.getBytes()
        if(exibitionInstance.save()){
            println 'SAVED!'
        }
        if(exibitionInstance.flier==null){
            flash.message = "Flier not uploaded"
        }else{
            flash.message = "Flier uploaded"
        }
    }
    redirect (action:'index')
}

The controller prints "SAVED" and give me the flash message "Flier uploaded" and i can print the contents of the flier longblob attribute.

But when controller ends, i have a NULL in the flier column in my database:

Database

UPDATE:

I figured it out. I could insert the pdf from mySql workbench setting the column manually. Then i could download the pdf from grails. So the bug had to be in the controller. The controller method uploadFlier() was not @Transactional (and read-only). After the change i got the error: com.mysql.jdbc.PacketTooBigException: Packet for query is too large.

After the fix everthing works.

Community
  • 1
  • 1
LeoFaber
  • 21
  • 4
  • Change your constraint to make flier nullable: false and see if you get a relevant error message back. Maybe something is happening on flush that you're just not seeing. Side note: don't save domains in controllers. Move that to a transactional service. – Gregg May 22 '15 at 15:32
  • Thanks Gregg, ill try it tomorrow. I move the controller code to a transactional service to mantain the decoupling? – LeoFaber May 22 '15 at 19:09
  • Maintain the decoulping yes, But also it is just a better pattern. Controllers being transactional in the newer versions of Grails was a side effect of improving the API. Controllers are meant to take a request and send a response; deal with HTTP stuff. Everything in between should be done by some other layer. – Gregg May 22 '15 at 20:17

0 Answers0