0 0

使用JPA遇到的OneToMany加载不正常问题10

我使用的是Netbeans6.1开发。JPA的实现是Toplink,数据库MySQL5.0.67。Toplink和jdbc驱动用的都是Netbeans自带的。现在的问题是我的一个类里面有一个Set集合。我启动机器的时候,第一次读可以读取这个集合的情况。比如Set里面有3条记录,那么刚开始的时候可以正常读取这3条。
但是如果数据库表变了,增加了一条,那么Set集合里居然不能正确读取,还是3条。我真是奇怪了,这是什么问题?
持久化配置
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="QAPU" transaction-type="RESOURCE_LOCAL">
        <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="toplink.platform.class.name" value="oracle.toplink.essentials.platform.database.MySQL4Platform"/>
            <property name="toplink.ddl-generation" value="create-tables"/>
            <property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/qa"/>
            <property name="toplink.jdbc.user" value="root"/>
            <property name="toplink.jdbc.password" value="810424"/>
        </properties>
    </persistence-unit>
</persistence>

然后是两个类
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.miao.domain.qa;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.Version;
import org.miao.domain.person.Person;
import org.miao.domain.resource.Type;

/**
 * 问题
 * @author Miao
 * @version 0.1
 */
@Entity
public class Question implements Serializable {

    private static final long serialVersionUID = 1L;
    
    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    /**
     * 提问者
     */
    @ManyToOne
    private Person questioner;
    
    /**
     * 标题
     */
    private String title;
    
    /**
     * 提问时间
     */
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date createTime = new Date();
    
    /**
     * 问题结束时间
     */
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date endTime;
    
    /**
     * 问题内容
     */
    private String content;
    
    /**
     * 补充说明
     */
    private String supplement;
    
    /**
     * 最后补充时间
     */
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date supplementDate;
    
    /**
     * 解决时间
     */
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date solveDate;
    
    /**
     * 赏金
     */
    private Integer reward = 0;
    
    /**
     * 最佳答案
     */
    @OneToOne
    private Answer selectedAnswer;
    
    /**
     * 所有答案
     */
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="question")
    private Set<Answer> answers;
    
    /**
     * 状态
     */
    @Enumerated
    private QuestionState questionState = QuestionState.待解决;
    
    /**
     * 分类
     */
    @ManyToOne
    private Type type;
    
    /**
     * version
     */
    @Version
    private Long version;
    
    /**
     * 构造方法
     */
    public Question() {
        
    }
    
    /**
     * 带参数构造方法
     * @param title
     * @param content
     * @param reward
     * @param type
     * @param questioner
     */
    public Question(String title, String content, Integer reward, Type type, Person questioner) {
        this.title = title;
        this.content = content;
        this.reward = reward;
        this.type = type;
        this.questioner = questioner;
    }

    /**
     * 获得主键
     * @return 主键
     */
    public Long getId() {
        return id;
    }

    /**
     * 设置主键
     * @param id 主键
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * 追加赏金
     * @param reward 赏金
     */
    public void addReward(Integer reward) {
        this.setReward((Integer) (this.reward + reward));
    }

    @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 Question)) {
            return false;
        }
        Question other = (Question) 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 title;
    }
    
    /**
     * 用户是否是问题提问者
     * @param person 用户
     * @return 是否是提问者
     */
    public boolean isQuestioner(Person person) {
        return questioner.equals(person);
    }

    /**
     * 获得所有答案
     * @return 所有答案
     */
    public Set<Answer> getAnswers() {
        return answers;
    }

    /**
     * 设置所有答案
     * @param answers 所有答案
     */
    public void setAnswers(Set<Answer> answers) {
        this.setAnswers(answers);
    }

    /**
     * 获得标题
     * @return 标题
     */
    public String getTitle() {
        return title;
    }

    /**
     * 设置标题
     * @param title 标题
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * 获得提问时间
     * @return 提问时间
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * 设置提问时间
     * @param createTime 提问时间
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * 获得问题结束时间
     * @return 问题结束时间
     */
    public Date getEndTime() {
        return endTime;
    }

    /**
     * 设置问题结束时间
     * @param endTime 问题结束时间
     */
    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    /**
     * 获得问题内容
     * @return 问题内容
     */
    public String getContent() {
        return content;
    }

    /**
     * 设置问题内容
     * @param content 问题内容
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * 获得补充说明
     * @return 补充说明
     */
    public String getSupplement() {
        return supplement;
    }

    /**
     * 设置补充说明
     * @param supplement 补充说明
     */
    public void setSupplement(String supplement) {
        this.supplement = supplement;
    }

    /**
     * 获得最后补充时间
     * @return 最后补充时间
     */
    public Date getSupplementDate() {
        return supplementDate;
    }

    /**
     * 设置最后补充时间
     * @param supplementDate 最后补充时间
     */
    public void setSupplementDate(Date supplementDate) {
        this.supplementDate = supplementDate;
    }

    /**
     * 获得解决时间
     * @return 解决时间
     */
    public Date getSolveDate() {
        return solveDate;
    }

    /**
     * 设置解决时间
     * @param solveDate 解决时间
     */
    public void setSolveDate(Date solveDate) {
        this.solveDate = solveDate;
    }

    /**
     * 获得赏金
     * @return 赏金
     */
    public Integer getReward() {
        return reward;
    }

    /**
     * 设置赏金
     * @param reward 赏金
     */
    public void setReward(Integer reward) {
        this.reward = reward;
    }

    /**
     * 获得最佳答案
     * @return 最佳答案
     */
    public Answer getSelectedAnswer() {
        return selectedAnswer;
    }

    /**
     * 设置最佳答案
     * @param selectedAnswer 最佳答案
     */
    public void setSelectedAnswer(Answer selectedAnswer) {
        this.selectedAnswer = selectedAnswer;
    }
        
    /**
     *获得提问者
     * @return 提问者
     */
    public Person getQuestioner() {
        return questioner;
    }

    /**
     * 设置提问者
     * @param questioner 提问者
     */
    public void setQuestioner(Person questioner) {
        this.questioner = questioner;
    }

    /**
     * 获得状态
     * @return 状态
     */
    public QuestionState getQuestionState() {
        return questionState;
    }

    /**
     * 设置状态
     * @param questionState 状态
     */
    public void setQuestionState(QuestionState questionState) {
        this.questionState = questionState;
    }

    /**
     * 获得分类
     * @return 分类
     */
    public Type getType() {
        return type;
    }

    /**
     * 设置分类
     * @param type 分类
     */
    public void setType(Type type) {
        this.type = type;
    }

    /**
     * 获得version
     * @return version
     */
    public Long getVersion() {
        return version;
    }

    /**
     * 设置version
     * @param version version
     */
    public void setVersion(Long version) {
        this.version = version;
    }

}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.miao.domain.qa;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.Version;
import org.miao.domain.person.Person;

/**
 * 答案
 * @author Miao
 */
@Entity
public class Answer implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    /**
     * 答题者
     */
    @ManyToOne
    private Person answerer;
    
    /**
     * 问题
     */
    @ManyToOne
    private Question question;
    
    /**
     * 内容
     */
    private String content;
    
    /**
     * 回答时间
     */
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date answerTime = new Date();
    
    /**
     * version
     */
    @Version
    private Long version;

    /**
     * 获得主键
     * @return 主键
     */
    public Long getId() {
        return id;
    }

    /**
     * 设置主键
     * @param id 主键
     */
    public void setId(Long id) {
        this.id = id;
    }

    @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 Answer)) {
            return false;
        }
        Answer other = (Answer) 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 content;
    }
    
    /**
     * 获得答题者
     * @return 答题者
     */
    public Person getAnswerer() {
        return answerer;
    }

    /**
     * 设置答题者
     * @param answerer 答题者
     */
    public void setAnswerer(Person answerer) {
        this.answerer = answerer;
    }

    /**
     * 获得问题
     * @return 问题
     */
    public Question getQuestion() {
        return question;
    }

    /**
     * 设置问题
     * @param question 问题
     */
    public void setQuestion(Question question) {
        this.question = question;
    }

    /**
     * 获得内容
     * @return 内容
     */
    public String getContent() {
        return content;
    }

    /**
     * 设置内容
     * @param content 内容
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * 获得回答时间
     * @return 回答时间
     */
    public Date getAnswerTime() {
        return answerTime;
    }

    /**
     * 设置回答时间
     * @param answerTime 回答时间
     */
    public void setAnswerTime(Date answerTime) {
        this.answerTime = answerTime;
    }

    /**
     * 获得version
     * @return version
     */
    public Long getVersion() {
        return version;
    }

    /**
     * 设置version
     * @param version version
     */
    public void setVersion(Long version) {
        this.version = version;
    }

}



就是Question带的answers集合不能正确加载。明明数据库里面已经多了新记录,就是无法加载,还是只加载老记录。非得重新启动,才能正确加载。看起来好像没读数据库,只是读缓存一样,但是我没有设置缓存呀。
如果明确设置缓存为NONE则报错。

已经解决。不能用new Answer然后直接持久化Answer。必须先拿到Question,然后把Answer添加到Set里面,最后更新Question,由系统自动持久化Answer。这样才可以。被长久用Hibernate限制住了。确实是加了缓存和不加完全不一样。看了一下说明,Toplink自动有缓存的。全关缓存会造成缓冲区堆栈溢出。
DAO 
2008年11月03日 23:03
目前还没有答案

相关推荐

    11_传智播客JPA详解_JPA中的一对多延迟加载与关系维护

    在JPA中,我们通过在实体类上使用`@OneToMany`注解来定义这种关系。这个注解允许我们将一个实体的集合属性映射到另一个实体的主键。 二、延迟加载(Lazy Loading) 延迟加载是一种优化策略,它只在真正需要数据时...

    spring boot 整合JPA及使用方法

    JPA支持各种关系映射,包括一对一(@OneToOne)、一对多(@OneToMany)、多对一(@ManyToOne)和多对多(@ManyToMany)。通过这些注解,开发者可以清晰地定义实体间的关系,使得数据库操作更加直观和方便。 8. 实体...

    JPA学习笔记(高手笔记录)

    在JPA开发过程中,可能会遇到如实体不存在、并发控制问题、数据一致性异常等错误。理解这些异常的含义并妥善处理是成功使用JPA的关键。 总结,JPA作为Java的持久化框架,简化了数据库操作,通过注解和元数据实现了...

    JPA中的一对多双向关联与级联操作

    然而,如果不正确地使用懒加载,可能会遇到“懒加载异常”。瞬时状态的管理则涉及到在操作关联实体时,确保它们都处于持久态,以避免丢失数据。 总的来说,理解并熟练掌握JPA中的一对多双向关联和级联操作,能够...

    JPA 实现继承关系

    在实际项目中,你可能会遇到的问题包括如何处理继承层次结构中的懒加载、如何优化查询效率、如何处理多态查询等。通过阅读和理解JPA的源码,以及使用相关工具,如Hibernate作为JPA的实现,可以帮助你更好地理解和...

    开发JPA应用.pdf

    - **JPA的目标**:JPA旨在提供一种统一的ORM解决方案,使得开发者可以在不修改业务逻辑的情况下轻松切换底层的ORM实现。这不仅提高了应用的灵活性,也简化了维护工作。 - **JPA的特点**: - 使用**标注**作为配置...

    Spring Data JPA

    - **Entity映射**:JPA允许我们通过@Entity注解将Java类映射到数据库表,通过@Id指定主键字段,并使用@OneToMany、@ManyToOne、@OneToOne和@ManyToMany等注解定义关系映射。 - **Query方法命名规则**:Spring Data ...

    hibernate常见异常针对于jpa

    3. **加载策略:** `@ManyToOne`默认使用立即加载,`@OneToMany`默认使用懒加载。 **示例代码:** ```java @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "parent_id") private ParentEntity parent; @...

    01_JPA详解_全面阐释和精彩总结JPA.zip

    10. **实战应用**:通过实际案例演示如何在Spring Boot或其它Java应用框架中集成JPA,以及解决实际开发中可能遇到的问题。 这个资料包《01_JPA详解_全面阐释和精彩总结JPA》应该会涵盖以上所有知识点,并可能包含...

    JPA 与hibernate所需jar包

    整合JPA与Hibernate使得开发者可以专注于业务逻辑,而不是底层数据库操作,同时,由于Hibernate的广泛使用和社区支持,遇到问题时通常能找到丰富的解决方案。正确配置和使用这两个工具,可以大大提高Java应用的开发...

    hibernate 中 fetch=FetchType.LAZY 懒加载失败处理方法

    当我们在 Hibernate 中使用懒加载特性时,可能会遇到 LazyInitializationException 异常,这是因为 Hibernate 的 Session 生命周期太短,导致了懒加载失败。 为了解决这个问题,我们可以使用 Spring 提供的一个支持...

    Ejb3-OneToMany--Good.rar

    在博客链接中,可能详细讲解了`@OneToMany`关系的实践案例,包括如何配置、使用和优化,以及可能遇到的问题和解决方案。访问这个链接可以获取更多关于EJB3中一对多关系映射的深入理解和实用技巧。 总之,`@...

    JPA2.0 javax.persistence src 源码

    Java Persistence API(JPA)是Java平台上的一个标准,用于管理关系数据库中的对象-关系映射(ORM)。JPA 2.0是该规范的一个重要版本,它在JPA ...这有助于在遇到问题时进行调试,或者在设计自己的ORM框架时作为参考。

    集成spring的hibernate懒加载

    然而,在实际应用中,我们常常会遇到一个名为“懒加载”(Lazy Loading)的问题,这在标题和描述中被提及。懒加载是一种优化策略,用于推迟对关联对象的加载,直到真正需要它们的时候。这种设计可以提高系统的性能,...

    JPA的学习笔记(java注解,事物)

    在使用JPA的过程中,可能会遇到一些常见的异常,比如: - `javax.persistence.TransactionRequiredException`:当试图执行需要事务的操作时但当前没有事务。 - `javax.persistence.EntityNotFoundException`:当尝试...

    Java标准版的EJB Persistence(二)

    为了解决这个问题,我们可以将@OneToMany注解的fetch属性设置为FetchType.EAGER,强制在加载Address对象时同时加载其residents集合。但这种做法可能导致不必要的性能开销,因为它可能会加载大量相关数据。如果仅需在...

    HibernateJPA

    理解并熟练掌握Hibernate JPA的各种特性和用法,对于Java开发者来说是必不可少的技能。在实际项目中,可以根据需求选择合适的配置和策略,充分利用Hibernate JPA的优势,构建高效稳定的企业级应用。

    Hibernate映射导致的几个异常

    2. **`EntityNotFoundException`:** 当尝试加载不存在的实体时,会抛出此异常。确保在持久化或检索对象时,主键值正确无误,且数据库中存在对应记录。同时,检查`&lt;id&gt;`标签下的`generator`配置,确保其与数据库中的...

    Hibernate5用户手册中文版

    **Hibernate 5 用户手册中文版** Hibernate 是一个流行的开源对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。...手册中的实例和解决方案将帮助读者解决在使用过程中遇到的各种问题。

    hibernate-entitymanager-3.2.0.GA.zip

    在实际应用中,可能会遇到各种问题,如懒加载异常、级联操作不当、缓存问题等。了解Hibernate的日志配置和错误信息,可以帮助开发者快速定位和解决问题。 7. 进阶学习: 学习Hibernate EM 3.2.0.GA,除了基本的...

Global site tag (gtag.js) - Google Analytics