2013-03-03 3 views
1

У меня есть основная проблема с моей таблицей базы данных оракула, тогда как я использую JPA.oracle db id column auto generate JPA JSF

Моя проблема: я создаю таблицу в базе данных, добавив ее в столбец идентификатора. Когда я возвращаюсь к моему проекту JPA, и когда я пытаюсь создать новую запись, он не создает идентификатор для нового. Он всегда говорит: произошла ошибка, пытающаяся отменить транзакцию.

Я ищу о проблеме. В основном это не автоматически генерирует значение ID. Вот мой JPA класс контроллера:

@Entity 
@Table(name = "PROJECTS", catalog = "", schema = "PROJETAKIP") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "Projects.findAll", query = "SELECT p FROM Projects p"), 
    @NamedQuery(name = "Projects.findById", query = "SELECT p FROM Projects p WHERE p.id = :id"), 
    @NamedQuery(name = "Projects.findByProject", query = "SELECT p FROM Projects p WHERE p.project = :project")}) 
public class Projects implements Serializable { 
    private static final long serialVersionUID = 1L; 
    // @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation 
    @Id 
    @Basic(optional = false) 
    @Column(name = "ID", nullable = false, precision = 0, scale = -127) 
    @GeneratedValue(strategy= GenerationType.SEQUENCE) 
    private BigDecimal id; 
    @Column(name = "PROJECT", length = 255) 
    private String project; 

    public Projects() { 
    } 

    public Projects(BigDecimal id) { 
     this.id = id; 
    } 

    public BigDecimal getId() { 
     return id; 
    } 

    public void setId(BigDecimal id) { 
     this.id = id; 
    } 

    public String getProject() { 
     return project; 
    } 

    public void setProject(String project) { 
     this.project = project; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.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 Projects)) { 
      return false; 
     } 
     Projects other = (Projects) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "com.ibb.souce.Projects[ id=" + id + " ]"; 
    } 

} 

и вот мой JSFClass:

@ManagedBean(name = "projectsController") 
@SessionScoped 
public class ProjectsController implements Serializable { 

    @Resource 
    private UserTransaction utx = null; 
    @PersistenceUnit(unitName = "DenemelerPU") 
    private EntityManagerFactory emf = null; 
    private Projects current; 
    private DataModel items = null; 
    private ProjectsJpaController jpaController = null; 
    private PaginationHelper pagination; 
    private int selectedItemIndex; 

    public ProjectsController() { 
    } 

    public Projects getSelected() { 
     if (current == null) { 
      current = new Projects(); 
      selectedItemIndex = -1; 
     } 
     return current; 
    } 

    private ProjectsJpaController getJpaController() { 
     if (jpaController == null) { 
      jpaController = new ProjectsJpaController(utx, emf); 
     } 
     return jpaController; 
    } 

    public PaginationHelper getPagination() { 
     if (pagination == null) { 
      pagination = new PaginationHelper(10) { 
       @Override 
       public int getItemsCount() { 
        return getJpaController().getProjectsCount(); 
       } 

       @Override 
       public DataModel createPageDataModel() { 
        return new ListDataModel(getJpaController().findProjectsEntities(getPageSize(), getPageFirstItem())); 
       } 
      }; 
     } 
     return pagination; 
    } 

    public String prepareList() { 
     recreateModel(); 
     return "List"; 
    } 

    public String prepareView() { 
     current = (Projects) getItems().getRowData(); 
     selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex(); 
     return "View"; 
    } 

    public String prepareCreate() { 
     current = new Projects(); 
     selectedItemIndex = -1; 
     return "Create"; 
    } 

    public String create() { 
     try { 
      getJpaController().create(current); 
      JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ProjectsCreated")); 
      return prepareCreate(); 
     } catch (Exception e) { 
      JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured")); 
      return null; 
     } 
    } 

    public String prepareEdit() { 
     current = (Projects) getItems().getRowData(); 
     selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex(); 
     return "Edit"; 
    } 

    public String update() { 
     try { 
      getJpaController().edit(current); 
      JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ProjectsUpdated")); 
      return "View"; 
     } catch (Exception e) { 
      JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured")); 
      return null; 
     } 
    } 

    public String destroy() { 
     current = (Projects) getItems().getRowData(); 
     selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex(); 
     performDestroy(); 
     recreatePagination(); 
     recreateModel(); 
     return "List"; 
    } 

    public String destroyAndView() { 
     performDestroy(); 
     recreateModel(); 
     updateCurrentItem(); 
     if (selectedItemIndex >= 0) { 
      return "View"; 
     } else { 
      // all items were removed - go back to list 
      recreateModel(); 
      return "List"; 
     } 
    } 

    private void performDestroy() { 
     try { 
      getJpaController().destroy(current.getId()); 
      JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ProjectsDeleted")); 
     } catch (Exception e) { 
      JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured")); 
     } 
    } 

    private void updateCurrentItem() { 
     int count = getJpaController().getProjectsCount(); 
     if (selectedItemIndex >= count) { 
      // selected index cannot be bigger than number of items: 
      selectedItemIndex = count - 1; 
      // go to previous page if last page disappeared: 
      if (pagination.getPageFirstItem() >= count) { 
       pagination.previousPage(); 
      } 
     } 
     if (selectedItemIndex >= 0) { 
      current = getJpaController().findProjectsEntities(1, selectedItemIndex).get(0); 
     } 
    } 

    public DataModel getItems() { 
     if (items == null) { 
      items = getPagination().createPageDataModel(); 
     } 
     return items; 
    } 

    private void recreateModel() { 
     items = null; 
    } 

    private void recreatePagination() { 
     pagination = null; 
    } 

    public String next() { 
     getPagination().nextPage(); 
     recreateModel(); 
     return "List"; 
    } 

    public String previous() { 
     getPagination().previousPage(); 
     recreateModel(); 
     return "List"; 
    } 

    public SelectItem[] getItemsAvailableSelectMany() { 
     return JsfUtil.getSelectItems(getJpaController().findProjectsEntities(), false); 
    } 

    public SelectItem[] getItemsAvailableSelectOne() { 
     return JsfUtil.getSelectItems(getJpaController().findProjectsEntities(), true); 
    } 

    @FacesConverter(forClass = Projects.class) 
    public static class ProjectsControllerConverter implements Converter { 

     public Object getAsObject(FacesContext facesContext, UIComponent component, String value) { 
      if (value == null || value.length() == 0) { 
       return null; 
      } 
      ProjectsController controller = (ProjectsController) facesContext.getApplication().getELResolver(). 
        getValue(facesContext.getELContext(), null, "projectsController"); 
      return controller.getJpaController().findProjects(getKey(value)); 
     } 

     java.math.BigDecimal getKey(String value) { 
      java.math.BigDecimal key; 
      key = new java.math.BigDecimal(value); 
      return key; 
     } 

     String getStringKey(java.math.BigDecimal value) { 
      StringBuffer sb = new StringBuffer(); 
      sb.append(value); 
      return sb.toString(); 
     } 

     public String getAsString(FacesContext facesContext, UIComponent component, Object object) { 
      if (object == null) { 
       return null; 
      } 
      if (object instanceof Projects) { 
       Projects o = (Projects) object; 
       return getStringKey(o.getId()); 
      } else { 
       throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Projects.class.getName()); 
      } 
     } 
    } 
} 

Когда я назначить идентификатор вручную он работает отлично. Но я хочу, чтобы он автоматически генерировал значение. Как преодолеть это?

мой триггер: DELIMITER @@ CREATE OR REPLACE TRIGGER PROJETAKIP.PROJECTS_TRIGGER BEFORE INSERT ON PROJECTS REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT PROJECTS_SEQUENCE.nextval INTO :NEW.ID FROM dual;END; @@ DELIMITER ;

+0

Это проблема JPA, а не JSF. –

+0

Можете ли вы показать нам объект последовательности (db)? – esej

+1

Отключите этот триггер и используйте генератор этой последовательности - '@SequenceGenerator (name =" someIdGenerator ", sequenceName =" YourSequenceName ", allocSize = 1, initialValue = 1) @GeneratedValue (strategy = GenerationType.SEQUENCE, generator =" someIdGenerator ") '. – Lion

ответ

0

Sequence startegy

Это, как вы должны использовать генератор последовательности:

@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="seq") 

А класса: (., Например, после того, как @Entity)

@SequenceGenerator(name="seq", sequenceName="PROJECTS_SEQUENCE", initialValue=1) 

Это должно сработать для вас.

0

При сохранении объекта у меня была такая же ошибка. Моя причина состояла в том, что мы добавили диапазон MIN от 3 цифр к значению id. По умолчанию генерируется автоматически идентификатор будет начинаться с 1, 2, 3 ... я сделал:

@Id @GeneratedValue 
    @Basic(optional = false) 
    @Size(min = 1, max = 64, message = "ID must be between 1 and 64 characters") 
    private String id; 

Так что - в вашем случае - будьте осторожны с ид аннотаций - попробуйте запустить без окалины, мин и макс значения - см. результат. Например, попробуйте:

@Id 
    @Basic(optional = false) 
    @Column(name = "ID") 
    @GeneratedValue(strategy= GenerationType.AUTO) 
    private BigDecimal id;