Hibernate:程序运行将新创建的实体与先前程序运行中保留的实体以及已删除的实体一起保留

时间:2018-04-05 15:19:12

标签: java hibernate oracle-xe

这可能是关于hibernate的初学者问题。我正在做我的第一步,我设计了一个由大约10个实体组成的简单数据模型,我使用hibernate将它们保存到我的Oracle XE数据库中。现在我面临以下问题:第一次,当我执行事务以持久化某些实体时,它们会被正确保留。我验证数据存在于数据库中,然后我删除所有数据库表中的所有条目。我验证所有表都是空的。然后我再次运行我的程序来坚持一些新的实体 - 这里发生了一些非常奇怪的事情:之后我在我的数据库中找到了新的条目以及旧的条目,这些条目最后一次被保留并且我已经删除了!它们包含旧ID和旧数据字段!怎么会这样?即使我在程序第一次运行后关闭计算机,也会发生这种情况!它如何记住旧条目以及它们保存在哪里?你有什么想法吗?

一些可能有用的信息:

我正在使用注释(而不是配置文件)进行映射。

下面你看到用于持久化的类以及一个实体的例子(我只显示一个实体以避免问题太长)。

如您所见,我在EAGERMANY映射上使用FetchType = MANY(据我所知,这可确保所有相关实体立即与任何相关实体一起加载加载实体)。这有什么影响吗?

感谢您的帮助!

public class PersistenceManager {
    private static final SessionFactory factory = new Configuration().configure().buildSessionFactory(); 
    public static void sampleData() {

        try(Session session = factory.openSession()) {
            SampleDataLoader.loadSampleData(session);
        } catch(HibernateException e) {
            System.out.println("Exception during persisting! Message: " + e.getMessage());
            e.printStackTrace();
        }

    }
}

public class SampleDataLoader {

    static void loadSampleData(Session session) {

        Language french = new Language("French");
        Language german = new Language("German");

        Noun garcon = new Noun(french, "garcon", false);
        Noun junge = new Noun(german, "Junge", false);

        junge.addTranslation(garcon);

        ZUser user = new ZUser("Daniel", "password");
        user.setOwnLanguage(german);
        user.setEmail("abc@somemail.de");
        user.setDateRegistered(LocalDateTime.now());

        user.addForeignLanguage(french);

        Transaction transaction = session.beginTransaction();
        session.save(user);
        session.save(french);
        session.save(german);
        session.save(junge);
        transaction.commit();

    }
}

@Entity
public class ZUser {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @Column
    private String name;

    @Column
    private String password;

    @Column
    private String email;

    @Column
    private String picturePath;

    @Column
    private LocalDateTime dateRegistered;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="OWNLANGUAGE_ID")
    private Language ownLanguage;

    @ManyToMany(cascade = { CascadeType.ALL })
    @JoinTable(name="USER_LANGUAGE",
        joinColumns=@JoinColumn(name="USER_ID"),
        inverseJoinColumns=@JoinColumn(name="LANGUAGE_ID")
    )
    private Set<Language> foreignLanguages = new HashSet<>();

    public ZUser() {  }
    public ZUser(String n, String p) {
        name = n;
        password = p;
    }

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public String getPicturePath() { return picturePath; }
    public void setPicturePath(String picturePath) { this.picturePath = picturePath; }
    public LocalDateTime getDateRegistered() { return dateRegistered; }
    public void setDateRegistered(LocalDateTime dateRegistered) { this.dateRegistered = dateRegistered; }
    public Language getOwnLanguage() { return ownLanguage; }
    public void setOwnLanguage(Language ownLanguage) { this.ownLanguage = ownLanguage; }
    public void addForeignLanguage(Language language) {foreignLanguages.add(language);}
    public Set<Language> getForeignLanguages() {return Collections.unmodifiableSet(foreignLanguages); }

}

1 个答案:

答案 0 :(得分:0)

Jagger的评论澄清(见评论)。实际上,我使用Oracle SQL命令行来删除条目,我已经rgotten,我需要在删除后明确提交。解决方案非常简单:)