Facebookの壁のようなものをしようとしていますが、問題があります。@OneToMayコレクションの更新
私のDBは、ユーザー用と投稿用の2つのテーブルで作成されています。 各投稿には、ユーザへの参照(ユーザテーブルへの外部キー)があります。
私はそれを動作させようとしましたが、それは非常にうまくいって、各ユーザーは自分の投稿を挿入し、他人が作成したものを見ることができます。
新しい投稿を挿入すると、データベースに正しく挿入されますが、次のサーバーが再起動するまで表示されません。 マップされた投稿のコレクションは正しく更新されていないようです。そのため、Beanは最初に実行したときに見つけたものを返します。
は、ここでエンティティをマッピングするために使用されるコードです:
USER
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 20)
@Column(name = "username")
private String username;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 45)
@Column(name = "password")
private String password;
@Basic(optional = false)
@NotNull
@Column(name = "regDate")
@Temporal(TemporalType.DATE)
private Date regDate;
@Basic(optional = false)
@NotNull
@Column(name = "id")
private int id;
@Column(name = "birthDate")
@Temporal(TemporalType.DATE)
private Date birthDate;
@Size(max = 255)
@Column(name = "avatar")
private String avatar;
@Size(max = 45)
@Column(name = "name")
private String name;
@Size(max = 45)
@Column(name = "surname")
private String surname;
@OneToMany(mappedBy="utente", fetch = FetchType.EAGER)
private Collection<Post> posts;
POST
public class Post implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(name = "id")
private Integer id = 0;
@Basic(optional = false)
@NotNull
@Lob
@Size(min = 1, max = 65535)
@Column(name = "text")
private String text;
@Basic(optional = false)
@NotNull
@Column(name = "date")
@Temporal(TemporalType.DATE)
private Date date;
@Basic(optional = false)
@NotNull
@Column(name = "time")
@Temporal(TemporalType.TIME)
private Date time;
@JoinColumn(name = "user", referencedColumnName = "username")
@ManyToOne(fetch = FetchType.EAGER, optional = false)
private User user;
私はそれをどのように修正することができますか?
編集:
ここでは、投稿と連携するマネージドビーンがあります。ビーンは、その別のビーン(PostManager)を呼び出し、管理
@Named(value = "postsMB")
@RequestScoped
public class PostsMB {
@EJB
private UtenteFacadeLocal userFacade;
@EJB
private PostManagerLocal postManager;
protected String username;
/** Creates a new instance of PostsMB */
public PostsMB() {
}
protected List<Post> posts;
/**
* Get the value of posts
*
* @return the value of posts
*/
public List<Post> getPosts() {
//Let's see if we are trying to display posts from another user (passed with a GET param) or from the logged in user
username = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("username");
if (username != null && !username.isEmpty()) {
user = userFacade.find(username);
}
if (user == null) {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
user = (Utente) session.getAttribute("user");
if (user == null) {
return null;
}
}
//Once we've got the right user, we get all his posts
posts = new LinkedList<Post>(user.getPosts());
return posts;
}
public void insertPost() {
//We get the user from the session and we use it to insert the post
user = (Utente) ((HttpSession) (FacesContext.getCurrentInstance().getExternalContext().getSession(false))).getAttribute("user");
postManager.insertPost(postText, user);
}
(postTextはゲッターとセッターを持つ別のプロパティです)のdataTableとポストを挿入するためのフォームを埋めるために)としてgetPostsを使用してJSFページ(で呼ばれています自動的に生成されたPostFacadeクラスを呼び出して、データをDBに挿入します。
ここに私のログイン方法
User u = userManager.doLogin(username, password);
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
session.setAttribute("username", u.getUsername());
だと、ここでの私としてgetPostsだ()メソッド:
@Stateless
public class PostManager implements PostManagerLocal {
@EJB
private PostFacadeLocal postFacade;
@Override
public void insertPost(Post post) {
postFacade.create(post);
}
@Override
public void insertPost(String text, User user) {
Post p = new Post();
p.setText(text);
p.setUser(user);
p.setDate(Calendar.getInstance().getTime());
p.setTime(Calendar.getInstance().getTime());
insertPost(p);
}
記事は、Userクラスでこのコードを
@OneToMany(mappedBy="user", fetch = FetchType.EAGER)
private Collection<Post> posts;
public Collection<Post> getPosts() {
return posts;
}
public void setPosts(Collection<Post> posts) {
this.posts = posts;
}
EDIT 2をretrivedていますポストマネージドビーン
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
user = utenteFacade.find(session.getAttribute("username));
posts = new LinkedList<Post>(user.getPosts());
これは私が前に言ったことを正確に行うはずなので、セッションにユーザー名(プレーンストリング)を格納してからファサードのfindメソッドを呼び出してユーザーの新しいインスタンスを取得します。 どうしたの?
EDIT 3:
UtenteFacade
@Stateless
public class UtenteFacade extends AbstractFacade<Utente> implements UtenteFacadeLocal {
@PersistenceContext(unitName = "LoginSession-ejbPU")
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public UtenteFacade() {
super(Utente.class);
}
}
AbstractFacade
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findRange(int[] range) {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = getEntityManager().createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
return q.getResultList();
}
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
Showは、投稿を作成して読むために使用するコードを使用して、トランザクションの開始とコミットを通知します。 –
ヒントは、コードで母国語を使用しないでください。これは後でいつもあなたに噛み付くでしょう。例えば、このようなサイトで助けを求めるとき。 –