Hibernate 尝试插入在 Java Web 应用程序中甚至不存在的表中

问题描述

嗨,我正在尝试开发一个 Web 应用程序并且正在使用一个 h2 数据库。现在我正在研究一个应该在我的表“BEWERTETEABGABEN”中保存“bewerteteAbgaben”的课程

这是添加“bewerteteAbgabe”的bean:

@Named
@ViewScoped
@FacesConfig
public class BewertungAddBean implements Serializable {
    /**
     * Abgabenspeicher
     */
    @Inject
    private BewerteteAbgabedAO bewerteteAbgabedAO;

    /**
     * Aufgabenspeicher
     */
    @Inject
    private BewerteteAufgabedAO bewerteteAufgabedAO;

    /**
     * Umleitung
     */
    @Inject
    private ExternalContext externalContext;

    @Getter
    private TreeNode root;

    @Getter
    private  Abgabe abgabe;

    @Inject
    private AbgabedAO abgabedAO;

    @Getter
    private BewerteteAbgabe bewerteteAbgabe;

    @Getter
    private static List<Student> teilnehmer = new ArrayList<>();

    @Inject
    private StudentDAO studentDAO;

    @Getter
    private Student student;

    /**
     * Initialisiert diese Bean.
     */
    @postconstruct
    private void init() {
        Map<String,String> parameterMap = externalContext.getRequestParameterMap();
        String email = parameterMap.get("email");
        int id = Integer.parseInt(parameterMap.get("ID"));
        student = studentDAO.findByEmail(email).orElse(null);
        abgabe = abgabedAO.findById(id).orElse(null);
        teilnehmer.add(student);
        buildBewertungsbaum();
    }

    public void add() throws IOException {
        List<TreeNode> children = root.getChildren();
        BewerteteAufgabe bewerteteAufgabe;
        for (TreeNode child : children) {
            bewerteteAufgabe = (BewerteteAufgabe) child.getData();
            bewerteteAufgabedAO.insert(bewerteteAufgabe);
        }
        bewerteteAbgabedAO.insert(bewerteteAbgabe);
        externalContext.redirect("bewertung.xhtml");

    }

    private void buildBewertungsbaum() {
        bewerteteAbgabe = new BewerteteAbgabe(abgabe,teilnehmer,null);
        root = new DefaultTreeNode(bewerteteAbgabe,null);
        for (Aufgabe aufgabe : abgabe.getAufgaben()) {
            if (aufgabe.getTeilAufgaben().isEmpty()) {
                BewerteteAufgabe bewAufgabe = new BewerteteAufgabe(aufgabe,null);
                TreeNode node = new DefaultTreeNode(bewAufgabe,root);
            } else
                createBewertungsNode(aufgabe);
        }
    }

    private void createBewertungsNode(Aufgabe aufgabe) {
        for (Aufgabe teilaufgabe : aufgabe.getTeilAufgaben()) {
            if (teilaufgabe.getTeilAufgaben().isEmpty()) {
                BewerteteAufgabe bewAufgabe = new BewerteteAufgabe(teilaufgabe,root);
            } else
                createBewertungsNode(teilaufgabe);
        }
    }

    public static String studentenToString() {
        StringBuilder names = new StringBuilder();
        for (Student student : teilnehmer) {
            names.append(student.getVorname()).append(" ").append(student.getNachname());
            if (teilnehmer.size() > 1 && student != teilnehmer.get(teilnehmer.size() - 1))
                names.append(",");
        }
        return names.toString();
    }

}

这是 BewerteteAbgabe 类:

@Entity
@Table(name = "BEWERTETEABGABE")
@NoArgsConstructor
public class BewerteteAbgabe {
    /**
     * ID einer bewerteten Abgabe
     */
    @Id
    @NonNull
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private int ID;

    /**
     * Abgabe,die bewertet wird
     */
    @JoinColumn(name = "ABGABE")
    @Getter
    @Setter
    @ManyToOne(cascade = {CascadeType.ALL})
    private Abgabe abgabe;

    /**
     * Studenten,fuer die die Abgabe bewertet wird
     */
    @Setter
    @ManyToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL})
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Student> studenten;

    /**
     * Tutoren,die bewerten
     */
    @Setter
    @Transient //Todo: Hier muss eine neue Tabelle eingefügt werden.
    private List<User> tutoren;

    /**
     * Kommentar zur Bewertung
     */
    @Getter
    @Setter
    @NotBlank
    @NonNull
    @Column(name = "KOMMENTAR")
    private String kommentar;

    /**
     * Abgabenresultat eines Studenten
     */
    @Getter
    @Setter
    //@Column(name = "RESULTAT")
    @Transient //Todo: Neue Resultat-Tabelle joinen
    private ZwischenBewertung.Resultat resultat;

    /**
     * Map zwischen der Aufgabe und ihrer Bewertung
     */
    @Transient //Todo: Hier muss eine neue Tabelle eingefügt werden.
    private Map<Aufgabe,BewerteteAufgabe> bewertung = new HashMap<>();

    /**
     * Konstruktor
     *
     * @param abgabe    Zu bewertende Abgabe
     * @param studenten Student,zu welchem Abgabe gehoert
     * @param kommentar Kommentar zur Abgabe
     */
    public BewerteteAbgabe(Abgabe abgabe,List<Student> studenten,String kommentar) {
        this.abgabe = abgabe;
        this.studenten = studenten;
        this.kommentar = kommentar;
    }

    public BewerteteAbgabe(Abgabe abgabe,List<Student> studenten) {
        this.abgabe = abgabe;
        this.studenten = studenten;
    }

    /**
     * gibt Tutoren zurueck,die Aufgabe korrigiert haben
     *
     * @return Tutoren,die korrigiert haben
     */
    public List<User> getTutoren() {
        return new ArrayList<>(this.tutoren);
    }

    /**
     * gibt Studenten zurueck,die Abgabe gemacht haben
     *
     * @return Studenten der Abgabe
     */
    public List<Student> getStudenten() {
        return new ArrayList<>(this.studenten);
    }

    /**
     * Fuegt die Bewertung zur Aufgabe hinzu.
     *
     * @param bewerteteAufgabe,die Bewertung
     * @throws NullPointerException     BewerteteAufgabe ist null
     * @throws IllegalArgumentException wenn die {@link Aufgabe} nicht in der {@link Abgabe} vorhanden ist.
     */
    public void addBewerteteAufgabe(BewerteteAufgabe bewerteteAufgabe) {

        Objects.requireNonNull(bewerteteAufgabe);

        if (!abgabe.containsAufgabe(bewerteteAufgabe.getAufgabe()))
            throw new IllegalArgumentException(messageformat.format("Die ubergebene Aufgabe {0} ist nicht in der Abgabe {1} enthalten.",abgabe.getAufgaben(),abgabe));

        bewertung.put(bewerteteAufgabe.getAufgabe(),bewerteteAufgabe);
    }

    /**
     * entfernt Bewertung einer Aufgabe
     *
     * @param bewerteteAufgabe bewerteteAufgabe,die entfernt werden soll
     * @return Erfolg
     * @throws NullPointerException     BewerteteAufgabe ist null
     * @throws IllegalArgumentException Aufgabe ist nicht in Bewertung
     */

    public boolean removeBewerteteAufgabe(BewerteteAufgabe bewerteteAufgabe) {
        if (bewerteteAufgabe == null) {
            throw new NullPointerException("bewerteteAufgabe ist null");
        }
        if (!(bewertung.containsKey(bewerteteAufgabe.getAufgabe()))) {
            throw new IllegalArgumentException("Aufgabe ist nicht in Bewertung");
        }
        return this.bewertung.remove(bewerteteAufgabe.getAufgabe(),bewerteteAufgabe);
    }

    /**
     * @param aufgabe Aufgabe,auf dessen Bewertung wir zugreifen wollen
     * @return Bewertung der Aufgabe
     * @throws NullPointerException     Aufgabe ist null
     * @throws IllegalArgumentException Aufgabe ist nicht in Abgabe
     */
    public BewerteteAufgabe getBewerteteAufgabe(Aufgabe aufgabe) {

        Objects.requireNonNull(aufgabe);

        if (!abgabe.containsAufgabe(aufgabe))
            throw new IllegalArgumentException(messageformat.format("Die ubergebene Aufgabe {0} ist nicht in der Abgabe {1} enthalten.",aufgabe,abgabe));

        return bewertung.get(aufgabe);
    }

    /**
     * berechnet Gesamtnote der Abgabe
     *
     * @return Gesamtnote
     */
    public ZwischenBewertung erstelleZwischenBewertung() {

        ErreichtePunkteAufgabenConsumer erreichtePunkteAufgabenConsumer = new ErreichtePunkteAufgabenConsumer(this);

        for (Aufgabe hauptAufgabe : abgabe.getAufgaben())
            hauptAufgabe.walkRecursiv(erreichtePunkteAufgabenConsumer);

        return new ZwischenBewertung(abgabe,erreichtePunkteAufgabenConsumer.summePunkte);
    }

    /**
     * Consumer,der ausrechnet wie viele Punkte gewichtet in einer Aufgabe erreicht wurden
     */
    private static class ErreichtePunkteAufgabenConsumer implements Consumer<Aufgabe> {

        /**
         * Gewichtete erreichte Punkte
         */
        public float summePunkte;

        /**
         * bewertete Abgabe fuer die Punkte summiert werden
         */
        private final BewerteteAbgabe bewerteteAbgabe;

        /**
         * Konstruktor
         *
         * @param bewerteteAbgabe beweretete Abgabe
         */
        public ErreichtePunkteAufgabenConsumer(BewerteteAbgabe bewerteteAbgabe) {
            this.bewerteteAbgabe = bewerteteAbgabe;
        }

        /**
         * Summiert die gewichteten Punkte fuer bewertete Aufgaben
         *
         * @param aufgabe Aufgabe,dessen erreichte Punkte summiert werden
         */
        @Override
        public void accept(Aufgabe aufgabe) {

            BewerteteAufgabe bewerteteAufgabe = bewerteteAbgabe.getBewerteteAufgabe(aufgabe);

            if (bewerteteAufgabe != null)
                summePunkte += bewerteteAufgabe.getErreichtePunkte() * aufgabe.getGewichtKumuliert();
        }
    }

}

这是 DAO:

@Singleton
public class BewerteteAbgabedAOImpl implements BewerteteAbgabedAO {
    @Override
    public void insert(BewerteteAbgabe bewerteteAbgabe) throws NullPointerException {
        HibernateUtil.execute(s -> s.save(bewerteteAbgabe));
    }

    @Override
    public void update(BewerteteAbgabe bewerteteAbgabe) throws NullPointerException {
        HibernateUtil.execute(s -> s.update(bewerteteAbgabe));
    }

    @Override
    public void delete(BewerteteAbgabe bewerteteAbgabe) {
        HibernateUtil.execute(s -> s.delete(bewerteteAbgabe));
    }

    @Override
    public List<BewerteteAbgabe> alleBewerteteAbgaben() {
        return HibernateUtil.find(s -> s.createquery("from BewerteteAbgabe ",BewerteteAbgabe.class).list());
    }

    @Override
    public Optional<BewerteteAbgabe> findById(int id) {
        return HibernateUtil.find(s -> Optional.ofNullable(s.get(BewerteteAbgabe.class,id)));
    }
}

这是我保存它们的表的 sql

CREATE TABLE `BewerteteAbgabe` (
                                   `id` INT NOT NULL AUTO_INCREMENT,`abgabe` INT NOT NULL,`kommentar` varchar(255),PRIMARY KEY (`id`)
);

现在,当我尝试添加“bewerteteAbgabe”时,我收到以下消息:

Caused by: org.h2.jdbc.JdbcsqlSyntaxErrorException: Table "BEWERTETEABGABE_STUDENT" not found; sql statement:
insert into BEWERTETEABGABE_STUDENT (BewerteteAbgabe_ID,studenten_EMAIL) values (?,?) [42102-200]

这是一张根本不存在的表。 欢迎提供任何帮助,因为我已经尝试解决这个问题几个小时了

解决方法

您在 BewerteteAbgabe 类和 Student 类之间定义了多对多关系。

@Setter
@ManyToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL})
@Fetch(value = FetchMode.SUBSELECT)
private List<Student> studenten;

Hibernate 尝试使用关系表对这种关系建模,其中包含每对学生和测试的条目。 该表自动以其连接的两个对象命名。

尝试并创建表格并在其中保存一些包含学生的 BewerteteAbgabe。您将在该表中看到您的类之间的连接。

看看https://www.baeldung.com/hibernate-many-to-many。有更详细的解释。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...