【问题标题】:No data being added to the Database except an I.D除了 I.D 之外,没有数据被添加到数据库中
【发布时间】:2014-03-20 05:26:53
【问题描述】:

我正在尝试添加用户在 u.i 上选择的值。到数据库中的特定列,我已经建立了与数据库的连接,当我按下保存时,一个新的 id 被添加到数据库中,控制台中没有显示错误,但是我要提交的值没有被放入数据库,我怎么能做到这一点?

这是图形用户界面的代码

                               <p:spinner id="ajaxspinner80-100" value="#{markingBean.spinnerNumber1}" 
                                           stepFactor = "1"  min="80" max="100" disabled = "#{formBean.number != 8}">  
                                    <p:ajax update="ajaxspinnervalue" process="@this" />  
                                </p:spinner> 
                    <p:commandButton action="#{markingBean.markSectionOne}" value="#{bundle.buttonSave}" update=":growl" icon="ui-icon-disk"/>

这是一个名为markingBean的bean

 private Marking markSectionOne;

    private MarkingService markingService;

    @Inject
    private MarkingFacade markingFacade;

    @PostConstruct
    public void init() {
        this.markSectionOne = new Marking();
    }

    public void markSectionOne() {
        this.markingFacade.create(this.markSectionOne);
        this.setMessage("Mark Saved");
    }

abstractFacade 中的 create 类

public void create(T entity) {
    getEntityManager().persist(entity);
}

这会导致在数据库中添加了一个id,而不是markSectionOne标记被添加到名为markSectionOne的列中,这是为什么呢,

标记的实体类是:

@Entity(name = "MARKING")
public class Marking implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String markingStage, markingCompleted, markSectionOne, markSectionTwo, markSectionThree, markSectionFour, markSectionFive, overalMark, plagorism, feedback, comments;

我得到错误的唯一一次是当我点击保存两次时,我在控制台中得到了错误:

WARNING:   Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL140219165944320' defined on 'MARKING'.
Error Code: -1
Call: INSERT INTO MARKING (ID, COMMENTS, FEEDBACK, MARKSECTIONFIVE, MARKSECTIONFOUR, MARKSECTIONONE, MARKSECTIONTHREE, MARKSECTIONTWO, MARKINGCOMPLETED, MARKINGSTAGE, OVERALMARK, PLAGORISM) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    bind => [12 parameters bound]

当有 12 列时,我是否只想添加一个值?

【问题讨论】:

  • 是否调用了托管 bean 操作?实体管理器是否保留数据?有错误信息要查看吗?
  • 根本没有错误消息要查看,我得到标记保存的 ajax 消息,控制台中什么都没有,并且 i.d.已添加到数据库中
  • 另外应该注意的是 i.ds 不是一个接一个的,它们是随机的
  • 看起来您没有在对象中填充数据。此外,请确保在保存后将 Marking 的新实例分配给您的 markSectionOne,这是在您的托管 bean 中。
  • 内部public void markSectionOnemarkSectionOne.setMarkingStage("foo"); this.markingFacade.create(this.markSectionOne); markSectionOne = new Marking();...

标签: java jsf jpa jsf-2


【解决方案1】:

你有两个问题:

  1. 您没有在将插入数据库的对象的字段中填充数据。
  2. 您正在尝试插入与上一个事务中使用的对象相同的对象,其中包含自动生成的 ID。由于此 id 是表的主键,因此当尝试插入具有已插入 id 的新行时,它会为您提供与重复唯一键或主键相关的错误消息。这是错误消息的相关部分:在唯一或主键约束中重复键值

解决问题:

  1. 更改方法的名称markSectionOne。您的类的任何方法都不应与其中的字段具有相同的名称。您可以将其更改为 saveMarkSectionOne 或有助于代码可读性的内容。
  2. 为您班级中的markSectionOne 字段创建 getter 和setter。这些方法被识别为getXxxsetXxx,驼峰式。在这种情况下,方法如下所示:

    public Marking getMarkSectionOne() {
        return this.markSectionOne;
    }
    public void setMarkSectionOne(Marking markSectionOne) {
        this.markSectionOne = markSectionOne;
    }
    

    完成这些更改后,现在您可以使用 JSF 的强大功能轻松地将数据绑定到您的视图。假设您的 Marking 类中有一个 int spinnerField 字段及其各自的 getter 和 setter,您可以将其绑定到微调器的值,如下所示:

    <!--
        This acts as markingBean.getMarkSectionOne.getSpinnerField() when rendering
        and as markingBean.getMarkSectionOne.setSpinnerField(spinner.getValue()) when sending the request to the server
    -->
    <p:spinner id="ajaxspinner80-100" value="#{markingBean.markSectionOne.spinnerField}"
        stepFactor="1"  min="80" max="100" disabled="#{formBean.number != 8}">
        <p:ajax update="ajaxspinnervalue" process="@this" />
    </p:spinner>
    

    对视图中的其他字段和组件执行类似操作。

  3. 最后但并非最不重要的一点是,您还应该在将markSectionOne 字段插入数据库后为其分配一个新实例。您可以通过在 saveMarkSectionOne 方法中创建一个新实例来实现这一点:

    public void markSectionOne() {
        //supposing the data in markSectionOne is filled...
        this.markingFacade.create(markSectionOne);
        this.setMessage("Mark Saved");
        //after saving...
        markSectionOne = new Marking();
    }
    

【讨论】:

  • @user2962401 检查部分答案:假设在您的Marking 类中有一个int spinnerField 字段...
  • 感谢我添加了一个私有的 int spinnerField;使用 getter 和 setter,但由于某种原因它仍然显示为未知属性
  • 对不起,你的意思是在标记实体类,而不是标记控制器类?
  • @user2962401 确保您的 markingBean 类具有用于您的 markSectionOne 字段的 getter 和 setter,以重新编译代码并重新部署应用程序。
  • @user2962401 我指的是Marking 类,而不是MarkingBean
猜你喜欢
  • 2017-10-08
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
相关资源
最近更新 更多