0

People と Story という 2 つのエンティティがあります。今は自分のストーリーを投稿して自分のストーリーをチェックしていますが、時々違うストーリーリストを返します。つまり、 usr.stories.hashCode() は、まったく同じユーザーからの異なるリクエストで同じではありません。データベース テーブルは常に正しいため、非常に混乱しています。詳細については、Hibernate リファレンスを調べましたが、まったく役に立ちませんでした。

モデルクラス:

@MappedSuperclass
public class People{
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer id;
    @OrderBy(value = "id DESC")
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "people")
    public List<Story> stories = new LinkedList<Story>();

    public People(){
    }
}

@MappedSuperclass
public class Story{
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "people_id")
    public People people;
    @Column(name = "story", nullable = false)
    public String story;

    public Story(String story){
        this.story = story;
    }
}

残りのクラス:

@Path("/story")
public class StoryRS {
    @POST
    public StreamingOutput create(final @Context HttpServletRequest req, final String story) throws IOException{
        return new StreamingOutput() {
           @Override
           public void write(OutputStream os) {
               HttpSession hs = req.getSession(false);
               if (hs != null && story != null && story.trim().length() > 0) {
                   Integer uid = (Integer) hs.getAttribute("uid");
                   People usr = uid != null ? PeopleDAO.findById(uid) : null;
                   if (usr != null) {
                      Story obj = new Story(story);
                      EntityManagerHelper.beginTransaction();
                      StoryDAO.save(obj);
                      EntityManagerHelper.commit();
                      os.write(obj.id);
                   }
               }
               os.close();
           }
        };
    }

    @GET
    public StreamingOutput create(final @Context HttpServletRequest req) throws IOException{
        return new StreamingOutput() {
           @Override
           public void write(OutputStream os) {
               HttpSession hs = req.getSession(false);
               if (hs != null && story != null && story.trim().length() > 0) {
                   Integer uid = (Integer) hs.getAttribute("uid");
                   People usr = uid != null ? PeopleDAO.findById(uid) : null;
                   if (usr != null && usr.stories != null && usr.stories.size()>0) {
                      os.write(usr.stories...);
                   }
               }
               os.close();
           }
        };
    }
}

人DAO:

public class PeopleDAO{
@Override
public void save(People entity) {
    try {
        getEntityManager().persist(entity);
    } catch (RuntimeException re) {
        EntityManagerHelper.log("save failed", Level.SEVERE, re);
        throw re;
    }
}

@Override
public void delete(People entity) {
    try {
        entity = getEntityManager().getReference(People.class, entity.getId());
        getEntityManager().remove(entity);
    } catch (RuntimeException re) {
        EntityManagerHelper.log("delete failed", Level.SEVERE, re);
        throw re;
    }
}

@Override
public People update(People entity) {
    try {
        People result = getEntityManager().merge(entity);
        return result;
    } catch (RuntimeException re) {
        EntityManagerHelper.log("update failed", Level.SEVERE, re);
        throw re;
    }
}

@Override
public People findById(Integer id) {
    try {
        People instance = getEntityManager().find(People.class, id);
        return instance;
    } catch (RuntimeException re) {
        EntityManagerHelper.log("find failed", Level.SEVERE, re);
        throw re;
    }
}

ストーリーDAO:

public class StoryDAO{
@Override
public void save(Story entity) {
    try {
        getEntityManager().persist(entity);
    } catch (RuntimeException re) {
        EntityManagerHelper.log("save failed", Level.SEVERE, re);
        throw re;
    }
    entity.People.stories.add(0, entity);
}

@Override
public void delete(Story entity) {
    try {
        entity = getEntityManager().getReference(Story.class, entity.getId());
        getEntityManager().remove(entity);
    } catch (RuntimeException re) {
        EntityManagerHelper.log("delete failed", Level.SEVERE, re);
        throw re;
    }
    entity.People.stories.remove(entity);
}

@Override
public Story update(Story entity) {
    try {
        Story result = getEntityManager().merge(entity);
        return result;
    } catch (RuntimeException re) {
        EntityManagerHelper.log("update failed", Level.SEVERE, re);
        throw re;
    }
}

@Override
public Story findById(Integer id) {
    try {
        Story instance = getEntityManager().find(Story.class, id);
        return instance;
    } catch (RuntimeException re) {
        EntityManagerHelper.log("find failed", Level.SEVERE, re);
        throw re;
    }
}

EntityManagerHelper:

public class EntityManagerHelper {
private static final EntityManagerFactory emf;
private static final ThreadLocal<EntityManager> threadLocal;
private static final Logger logger;

static {
    emf = Persistence.createEntityManagerFactory("db");
    threadLocal = new ThreadLocal<EntityManager>();
    logger = Logger.getLogger("db");
    logger.setLevel(Level.ALL);
}

public static EntityManager getEntityManager() {
    EntityManager manager = threadLocal.get();
    if (manager == null || !manager.isOpen()) {
        manager = emf.createEntityManager();
        threadLocal.set(manager);
    }
    return manager;
}

public static void closeEntityManager() {
    EntityManager em = threadLocal.get();
    threadLocal.set(null);
    if (em != null)
        em.close();
}

public static void beginTransaction() {
    getEntityManager().getTransaction().begin();
}

public static void commit() {
    getEntityManager().getTransaction().commit();
}

public static void rollback() {
    getEntityManager().getTransaction().rollback();
}

public static Query createQuery(String query) {
    return getEntityManager().createQuery(query);
}

返信ありがとうございます

4

1 に答える 1

0

これがあなたの問題です

public static EntityManager getEntityManager() {
    EntityManager manager = threadLocal.get();
    if (manager == null || !manager.isOpen()) {
        manager = emf.createEntityManager();
        threadLocal.set(manager);
    }
    return manager;
}

EntityManager は短命のオブジェクトであると想定されています。それらは作るのも破壊するのも安い。また、一貫性のない結果が得られる理由についても説明します。EntityManager には、驚くほどアグレッシブな内部キャッシュがあります。

EM を操作するためのルールは、「トランザクションごとに 1 つの EntityManager」です。

毎回新しい EM を取得するようにコードを変更すれば、問題は解消されます。

于 2013-05-12T14:32:38.637 に答える