【问题标题】:Hibernate trying to insert into Table that doesn't even exist in Java web applicationHibernate 尝试插入到 Java Web 应用程序中甚至不存在的表中
【发布时间】:2021-05-14 07:50:02
【问题描述】:

您好,我正在尝试开发 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, 0, 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, 0, null);
                TreeNode node = new DefaultTreeNode(bewAufgabe, 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]

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

【问题讨论】:

    标签: java sql hibernate h2 dao


    【解决方案1】:

    您在 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。有更详细的解释。

    【讨论】:

    • 感谢您的回答。我已经添加了表格,当我保存一个 bewerteteAbgabe 时,另一个 abgabe 正在被保存,你可能知道这是为什么吗?
    • 您有一个字段Abgabe abgabe,带有一个@ManyToOne 和一个@JoinColumn 注释。当您保存包含 Abgabe 的 BewerteteAbgabe 时,也会保存 Abgabe。原因是CascadeType.ALL。对父对象的所有操作都会传播到子对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多