title: Error testing auto-generated REST app using NetBeans+Glassfish+JAX-RS+JPA
body: <p>I developed a simple RESTful app using the NetBeans assistants for testing purposes. For this, I followed this video: <a href="https://www.youtube.com/watch?v=RNJynlcqHNs" rel="nofollow">https://www.youtube.com/watch?v=RNJynlcqHNs</a> . The process was a little bit different since I'm using the latest version of NetBeans, but it was supposed to have the same results. In resume I used the tools:</p>
  
  <ul>
  <li>NetBeans 8.1</li>
  <li>Glassfish Server 4.1.1</li>
  <li>MySQL (without any issue until now)</li>
  </ul>
  
  <p>The assistants:</p>
  
  <ul>
  <li>Entity Classes from Database</li>
  <li>RESTful Services from Entity Classes</li>
  <li>RESTful Javascript Client (which uses Backbone+HTML5 to build a "fully functional" client)</li>
  </ul>
  
  <p>As far as I know, the project includes EclipseLink (JPA 2.1) and Jersey.</p>
  
  <p>The project deploys right, and I can access the services from the browser directly, but when I try to use the auto-generated Javascript client to access the services it doesn't load completely. Additionaly, I get this error in the browser's console:</p>
  
  <blockquote>
    <p>Failed to load resource: the server responded with a status of 500 (Internal Server Error)</p>
  </blockquote>
  
  <p>And I get this error in NetBeans/Glassfish "console":</p>
  
  <pre><code>Advertencia:   StandardWrapperValve[service.ApplicationConfig]: Servlet.service() for servlet service.ApplicationConfig threw exception
  
  java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
  
  at org.eclipse.persistence.jaxb.JAXBBeanValidator.isConstrainedObject(JAXBBeanValidator.java:257)
  
  at org.eclipse.persistence.jaxb.JAXBBeanValidator.shouldValidate(JAXBBeanValidator.java:208)
  
  etc...
  </code></pre>
  
  <p>This is the JPA entity class code:</p>
  
  <pre><code>package model;
  
  import java.io.Serializable;
  import java.util.List;
  import javax.persistence.Basic;
  import javax.persistence.CascadeType;
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.Id;
  import javax.persistence.NamedQueries;
  import javax.persistence.NamedQuery;
  import javax.persistence.OneToMany;
  import javax.persistence.Table;
  import javax.validation.constraints.NotNull;
  import javax.validation.constraints.Size;
  import javax.xml.bind.annotation.XmlRootElement;
  import javax.xml.bind.annotation.XmlTransient;
  
  /**
   *
   * @author USER
   */
  @Entity
  @Table(name = "oficina")
  @XmlRootElement
  @NamedQueries({
      @NamedQuery(name = "Oficina.findAll", query = "SELECT o FROM Oficina o"),
      @NamedQuery(name = "Oficina.findByIdOficina", query = "SELECT o FROM Oficina o WHERE o.idOficina = :idOficina"),
      @NamedQuery(name = "Oficina.findByNumero", query = "SELECT o FROM Oficina o WHERE o.numero = :numero"),
      @NamedQuery(name = "Oficina.findByDescripcion", query = "SELECT o FROM Oficina o WHERE o.descripcion = :descripcion")})
  public class Oficina implements Serializable {
  
      private static final long serialVersionUID = 1L;
      @Id
      @Basic(optional = false)
      @NotNull
      @Column(name = "id_oficina")
      private Integer idOficina;
      @Basic(optional = false)
      @NotNull
      @Size(min = 1, max = 10)
      @Column(name = "numero")
      private String numero;
      @Size(max = 100)
      @Column(name = "descripcion")
      private String descripcion;
      @OneToMany(cascade = CascadeType.ALL, mappedBy = "idOficina")
      private List&lt;Investigador&gt; investigadorList;
  
      public Oficina() {
      }
  
      public Oficina(Integer idOficina) {
          this.idOficina = idOficina;
      }
  
      public Oficina(Integer idOficina, String numero) {
          this.idOficina = idOficina;
          this.numero = numero;
      }
  
      public Integer getIdOficina() {
          return idOficina;
      }
  
      public void setIdOficina(Integer idOficina) {
          this.idOficina = idOficina;
      }
  
      public String getNumero() {
          return numero;
      }
  
      public void setNumero(String numero) {
          this.numero = numero;
      }
  
      public String getDescripcion() {
          return descripcion;
      }
  
      public void setDescripcion(String descripcion) {
          this.descripcion = descripcion;
      }
  
      @XmlTransient
      public List&lt;Investigador&gt; getInvestigadorList() {
          return investigadorList;
      }
  
      public void setInvestigadorList(List&lt;Investigador&gt; investigadorList) {
          this.investigadorList = investigadorList;
      }
  
      @Override
      public int hashCode() {
          int hash = 0;
          hash += (idOficina != null ? idOficina.hashCode() : 0);
          return hash;
      }
  
      @Override
      public boolean equals(Object object) {
          // TODO: Warning - this method won't work in the case the id fields are not set
          if (!(object instanceof Oficina)) {
              return false;
          }
          Oficina other = (Oficina) object;
          if ((this.idOficina == null &amp;&amp; other.idOficina != null) || (this.idOficina != null &amp;&amp; !this.idOficina.equals(other.idOficina))) {
              return false;
          }
          return true;
      }
  
      @Override
      public String toString() {
          return "model.Oficina[ idOficina=" + idOficina + " ]";
      }
  
  }
  </code></pre>
  
  <p>This is the service code:</p>
  
  <pre><code>package service;
  
  import java.util.List;
  import javax.ejb.Stateless;
  import javax.persistence.EntityManager;
  import javax.persistence.PersistenceContext;
  import javax.ws.rs.Consumes;
  import javax.ws.rs.DELETE;
  import javax.ws.rs.GET;
  import javax.ws.rs.POST;
  import javax.ws.rs.PUT;
  import javax.ws.rs.Path;
  import javax.ws.rs.PathParam;
  import javax.ws.rs.Produces;
  import javax.ws.rs.core.MediaType;
  import model.Oficina;
  
  /**
   *
   * @author USER
   */
  @Stateless
  @Path("oficinas")
  public class OficinaFacadeREST extends AbstractFacade&lt;Oficina&gt; {
  
      @PersistenceContext(unitName = "grupoItosWSPU")
      private EntityManager em;
  
      public OficinaFacadeREST() {
          super(Oficina.class);
      }
  
      @POST
      @Override
      @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
      public void create(Oficina entity) {
          super.create(entity);
      }
  
      @PUT
      @Path("{id}")
      @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
      public void edit(@PathParam("id") Integer id, Oficina entity) {
          super.edit(entity);
      }
  
      @DELETE
      @Path("{id}")
      public void remove(@PathParam("id") Integer id) {
          super.remove(super.find(id));
      }
  
      @GET
      @Path("{id}")
      @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
      public Oficina find(@PathParam("id") Integer id) {
          return super.find(id);
      }
  
      @GET
      @Override
      @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
      public List&lt;Oficina&gt; findAll() {
          return super.findAll();
      }
  
      @GET
      @Path("{from}/{to}")
      @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
      public List&lt;Oficina&gt; findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
          return super.findRange(new int[]{from, to});
      }
  
      @GET
      @Path("count")
      @Produces(MediaType.TEXT_PLAIN)
      public String countREST() {
          return String.valueOf(super.count());
      }
  
      @Override
      protected EntityManager getEntityManager() {
          return em;
      }
  
  }
  </code></pre>
  
  <p>And finally, this is the Javascript code:</p>
  
  <pre><code>var app = {
      // Create this closure to contain the cached modules
      module: function () {
          // Internal module cache.
          var modules = {};
  
          // Create a new module reference scaffold or load an
          // existing module.
          return function (name) {
              // If this module has already been created, return it.
              if (modules[name]) {
                  return modules[name];
              }
  
              // Create a module and save it under this name
              return modules[name] = {Views: {}};
          };
      }()
  };
  
  (function (models) {
  
  // Model for Oficina entity
      models.Oficina = Backbone.Model.extend({
          urlRoot: "http://localhost:8080/grupoItosWS/api/oficinas/",
          idAttribute: 'idOficina',
          defaults: {
              descripcion: "",
              numero: ""
          },
          toViewJson: function () {
              var result = this.toJSON(); // displayName property is used to render item in the list
              result.displayName = this.get('idOficina');
              return result;
          },
          isNew: function () {
              // default isNew() method imlementation is
              // based on the 'id' initialization which
              // sometimes is required to be initialized.
              // So isNew() is rediefined here
              return this.notSynced;
          },
          sync: function (method, model, options) {
              options || (options = {});
              var errorHandler = {
                  error: function (jqXHR, textStatus, errorThrown) {
                      // TODO: put your error handling code here
                      // If you use the JS client from the different domain
                      // (f.e. locally) then Cross-origin resource sharing 
                      // headers has to be set on the REST server side.
                      // Otherwise the JS client has to be copied into the
                      // some (f.e. the same) Web project on the same domain
                      alert('Unable to fulfil the request');
                  }
              };
  
              if (method === 'create') {
                  options.url = 'http://localhost:8080/grupoItosWS/api/oficinas/';
              }
              var result = Backbone.sync(method, model, _.extend(options, errorHandler));
              return result;
          }
  
  
      });
  
  
      // Collection class for Oficina entities
      models.OficinaCollection = Backbone.Collection.extend({
          model: models.Oficina,
          url: "http://localhost:8080/grupoItosWS/api/oficinas/",
          sync: function (method, model, options) {
              options || (options = {});
              var errorHandler = {
                  error: function (jqXHR, textStatus, errorThrown) {
                      // TODO: put your error handling code here
                      // If you use the JS client from the different domain
                      // (f.e. locally) then Cross-origin resource sharing 
                      // headers has to be set on the REST server side.
                      // Otherwise the JS client has to be copied into the
                      // some (f.e. the same) Web project on the same domain
                      alert('Unable to fulfil the request');
                  }
              };
  
              var result = Backbone.sync(method, model, _.extend(options, errorHandler));
              return result;
          }
      });
  
  
  })(app.module("models"));
  
  (function (views) {
  
      views.ListView = Backbone.View.extend({
          tagName: 'tbody',
          initialize: function (options) {
              this.options = options || {};
              this.model.bind("reset", this.render, this);
              var self = this;
              this.model.bind("add", function (modelName) {
                  var row = new views.ListItemView({
                      model: modelName,
                      templateName: self.options.templateName
                  }).render().el;
                  $(self.el).append($(row));
                  $(self.el).parent().trigger('addRows', [$(row)]);
              });
          },
          render: function (eventName) {
              var self = this;
              _.each(this.model.models, function (modelName) {
                  $(this.el).append(new views.ListItemView({
                      model: modelName,
                      templateName: self.options.templateName
                  }).render().el);
              }, this);
              return this;
          }
      });
  
      views.ListItemView = Backbone.View.extend({
          tagName: 'tr',
          initialize: function (options) {
              this.options = options || {};
              this.model.bind("change", this.render, this);
              this.model.bind("destroy", this.close, this);
          },
          template: function (json) {
              /*
               *  templateName is element identifier in HTML
               *  $(this.options.templateName) is element access to the element
               *  using jQuery 
               */
              return _.template($(this.options.templateName).html())(json);
          },
          render: function (eventName) {
              $(this.el).html(this.template(this.model.toJSON()));
              return this;
          },
          close: function () {
              var table = $(this.el).parent().parent();
              table.trigger('disable.pager');
              $(this.el).unbind();
              $(this.el).remove();
              table.trigger('enable.pager');
          }
  
      });
  
      views.ModelView = Backbone.View.extend({
          initialize: function (options) {
              this.options = options || {};
              this.model.bind("change", this.render, this);
          },
          render: function (eventName) {
              $(this.el).html(this.template(this.model.toJSON()));
              return this;
          },
          template: function (json) {
              /*
               *  templateName is element identifier in HTML
               *  $(this.options.templateName) is element access to the element
               *  using jQuery 
               */
              return _.template($(this.options.templateName).html())(json);
          },
          /*
           *  Classes "save"  and "delete" are used on the HTML controls to listen events.
           *  So it is supposed that HTML has controls with these classes.
           */
          events: {
              "change input": "change",
              "click .save": "save",
              "click .delete": "drop"
          },
          change: function (event) {
              var target = event.target;
              console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
          },
          save: function () {
              // TODO : put save code here
              var hash = this.options.getHashObject();
              this.model.set(hash);
              if (this.model.isNew() &amp;&amp; this.collection) {
                  var self = this;
                  this.collection.create(this.model, {
                      success: function () {
                          // see isNew() method implementation in the model
                          self.model.notSynced = false;
                          self.options.navigate(self.model.id);
                      }
                  });
              } else {
                  this.model.save();
                  this.model.el.parent().parent().trigger("update");
              }
              return false;
          },
          drop: function () {
              this.model.destroy({
                  success: function () {
                      /*
                       *  TODO : put your code here
                       *  f.e. alert("Model is successfully deleted");
                       */
                      window.history.back();
                  }
              });
              return false;
          },
          close: function () {
              $(this.el).unbind();
              $(this.el).empty();
          }
      });
  
      // This view is used to create new model element
      views.CreateView = Backbone.View.extend({
          initialize: function (options) {
              this.options = options || {};
              this.render();
          },
          render: function (eventName) {
              $(this.el).html(this.template());
              return this;
          },
          template: function (json) {
              /*
               *  templateName is element identifier in HTML
               *  $(this.options.templateName) is element access to the element
               *  using jQuery 
               */
              return _.template($(this.options.templateName).html())(json);
          },
          /*
           *  Class "new" is used on the control to listen events.
           *  So it is supposed that HTML has a control with "new" class.
           */
          events: {
              "click .new": "create"
          },
          create: function (event) {
              this.options.navigate();
              return false;
          }
      });
  
  })(app.module("views"));
  
  
  $(function () {
      var models = app.module("models");
      var views = app.module("views");
  
      var AppRouter = Backbone.Router.extend({
          routes: {
              '': 'list',
              'new': 'create'
              ,
              ':id': 'details'
          },
          initialize: function () {
              var self = this;
              $('#create').html(new views.CreateView({
                  // tpl-create is template identifier for 'create' block
                  templateName: '#tpl-create',
                  navigate: function () {
                      self.navigate('new', true);
                  }
              }).render().el);
          },
          list: function () {
              this.collection = new models.OficinaCollection();
              var self = this;
              this.collection.fetch({
                  success: function () {
                      self.listView = new views.ListView({
                          model: self.collection,
                          // tpl-oficina-list-itemis template identifier for item
                          templateName: '#tpl-oficina-list-item'
                      });
                      $('#datatable').html(self.listView.render().el).append(_.template($('#thead').html())());
                      if (self.requestedId) {
                          self.details(self.requestedId);
                      }
                      var pagerOptions = {
                          // target the pager markup 
                          container: $('.pager'),
                          // output string - default is '{page}/{totalPages}'; possiblevariables: {page}, {totalPages},{startRow}, {endRow} and {totalRows}
                          output: '{startRow} to {endRow} ({totalRows})',
                          // starting page of the pager (zero based index)
                          page: 0,
                          // Number of visible rows - default is 10
                          size: 10
                      };
                      $('#datatable').tablesorter({widthFixed: true,
                          widgets: ['zebra']}).
                              tablesorterPager(pagerOptions);
                  }
              });
          },
          details: function (id) {
              if (this.collection) {
                  this.oficina = this.collection.get(id);
                  if (this.view) {
                      this.view.close();
                  }
                  var self = this;
                  this.view = new views.ModelView({
                      model: this.oficina,
                      // tpl-oficina-details is template identifier for chosen model element
                      templateName: '#tpl-oficina-details',
                      getHashObject: function () {
                          return self.getData();
                      }
                  });
                  $('#details').html(this.view.render().el);
              } else {
                  this.requestedId = id;
                  this.list();
              }
          },
          create: function () {
              if (this.view) {
                  this.view.close();
              }
              var self = this;
              var dataModel = new models.Oficina();
              // see isNew() method implementation in the model
              dataModel.notSynced = true;
              this.view = new views.ModelView({
                  model: dataModel,
                  collection: this.collection,
                  // tpl-oficina-details is a template identifier for chosen model element
                  templateName: '#tpl-oficina-details',
                  navigate: function (id) {
                      self.navigate(id, false);
                  },
                  getHashObject: function () {
                      return self.getData();
                  }
              });
              $('#details').html(this.view.render().el);
          },
          getData: function () {
              return {
                  idOficina: $('#idOficina').val(),
                  descripcion: $('#descripcion').val(),
                  numero: $('#numero').val()
              };
          }
      });
      new AppRouter();
  
  
      Backbone.history.start();
  });
  </code></pre>
  
  <p>I've been looking for a solution for a while but I haven't found it, additionaly the error is cryptic for me since I don't know so much about JAX-RS or Backbone. Has anyone had this issue before? Is there any solution?</p>