2017-01-07 13 views
0

Java EE에서 WebSocket 호출을 통해 데이터베이스에 항목을 추가하려고하지만 여전히 이것을 배우고 있습니다. 아직 모든 개념을 이해하지 못했습니다. 난 내 코드를 조정할 방법에 따라 다음과 같은 두 가지 오류를 얻을 :Java EE에서 엔티티를 유지하는 방법은 무엇입니까?

오류 없음 1 : java.lang.IllegalStateException : 예외 설명 : JTA를 사용하는 동안 EntityTransaction을 사용할 수 없습니다.

오류없이 2 : javax.persistence.TransactionRequiredException 내 DB에 아무것도 얻을 말할 필요도없이

. 아마 내 코드와 최적의 것보다 적은 일반적인 디자인에 많은 것들이 있습니다. 어떤 조언이나 포인터도 환영하지만, 질문은 데이터베이스로 내 사용자를 얻기 위해 여기에서 어디로 가야합니까?

전체적인 문제를 해결하기 전에 다음과 같은 간단한 설정으로 작업하고 있습니다.

내 엔티티는

:

@Entity 
@Table(name = "USER_TABLE") 
public class User implements Serializable { 

    @Id 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

사용자에 대한 마법의 DB 물건이 발생해야하는 위치 내 데이터 액세스 개체가, 결국 이것이다 :

public class UserDAO { 

    private EntityManager mEM; 

    public void save(User user) { 
     //mEM.getTransaction().begin(); // with comment = error no 2 | no comment = no 1 
     mEM.persist(user); // I was thinking that this was the magic I needed. 
     //mEM.getTransaction().commit(); // with comment = error no 2 | no comment = no 1 
    } 

    public void setEM(EntityManager em) { 
     mEM = em; 
    } 
} 

나는 또한 DatabaseIO이를, 내 생각은 만약 내가 단지 사용자 엔티티 이상을 가지고 있다면, 하나의 클래스에서 모든 데이터베이스 입출력 물건들을 수집하고 싶습니다 :

public class DatabaseIO { 

    private EntityManager mEM; 

    public DatabaseIO(EntityManager em) { 
     System.out.println("DatabaseIO(" + em + ")"); 
     mEM = em; 
    } 

    public void createUser(String name) { 
     System.out.println("createUser(" + name + ")"); 
     User user = new User(); 
     user.setName(name); 

     UserDAO userDAO = new UserDAO(); 
     userDAO.setEM(mEM); 
     userDAO.save(user); 
    } 
} 

그런 다음 데이터베이스 IO를 사용하고 응용 프로그램에 들어오는 요청을 처리 할 몇 가지 클래스가 있습니다. 기본적으로 비즈니스 논리. 모든 사용자가 응용 프로그램에 연결할 때 생성되는 Bean으로 표시하지 않았습니다. 일단 연결되면 user1이 user2의 SomeClass 객체에 액세스해야 할 수도 있습니다. 컨테이너가 아닌 객체를 직접 만들지 않고도이를 수행하는 방법을 모릅니다.

public class SomeClass { 

    private DatabaseIO mDbIO; 

    public SomeClass(EntityManager em) { 
     mDbIO = new DatabaseIO(em); 
    } 

    public void newUser(String name) { 
     mDbIO.createUser(name); 
    } 
} 

나는 나의 목표는 나는 종종 필요한 일을 두지했다, 응용 프로그램 시작 및 응용 프로그램의 모든이 더 나은 방법이 제일 (가장 가능성이 확실하지 않은 일부 상태를 유지하는 EJB가 데이터베이스에 나는) 그것으로 방법을 완성하고있어하지만 내가 지금까지 가지고 올 한 것을 때까지 :

@Startup 
@Singleton 
@Named("some_manager") 
public class SomeApplicationManager { 

    @PersistenceContext(unitName="AddUsersPU") 
    private EntityManager mEM; 

    public EntityManager getEM() { 
     return mEM; 
    } 
} 

그리고 마지막으로 내 웹 소켓 엔드 포인트 : 나는 이것을 테스트 한

@ServerEndpoint("/WebSocket") 
public class WebEndpoint { 

    @Inject 
    SomeApplicationManager mAppManager; 

    @OnOpen 
    public void onOpen(Session aSession, EndpointConfig aConfig) { 
     aSession.addMessageHandler(new MessageHandler.Whole<String>() { 
      @Override 
      public void onMessage(String aUserName) { 
       System.out.println("new user: " + aUserName); 
       SomeClass aClassObj = new SomeClass(mAppManager.getEM()); 
       aClassObj.newUser(aUserName); 
      } 
     }); 
    } 

} 

을 간단한 JavaScript 및 나는 내가 오류가 발생했다는 의견을 한 UserDAO의 줄까지 예상 한 의견을 얻습니다.

편집 : 아래 답변 및 일부 더 많은 검색에서 mEM.persist (사용자)가 작동하지 않는 이유는 컨테이너에서 관리하지 않기 때문입니다. 필자는 UserDAO에 @Stateless로 주석을 달고 @EJB를 통해 DatabaseIO에 삽입함으로써이 문제를 해결하려고했습니다. 그러나 이것은 나에게 NullPointerException을 주었다. 나는 또한 DatabaseIO와 SomeClass를 @Stateless로 표시하고 WebClient에서 WebClass의 SomeClass를 명시 적으로 생성하는 대신 @EJB를 삽입했다. 이 시점에서 나는 실제로 엔티티를 데이터베이스에 넣었지만 나는 그것을 모두 이해하고 있는지 확신 할 수 없다.

+0

나는 이것과 비슷한 것을했고 그것은 나를 위해 일했다. 제발보십시오 –

답변

0

UserDAO를 Session Bean으로 만들고 @PersistenceContext 주석을 사용하여 그 내부에 지속성 컨텍스트를 삽입하십시오. 오류 1의 이유는 JTA를 사용하고 있으므로 트랜잭션을 관리 할 수 ​​없으며 명시 적으로 트랜잭션을 지정하지 않는 한 EJB 메소드를 입력 할 때 트랜잭션이 발생합니다. 그리고 당신은 영속 컨텍스트를 제공하기 위해 어떤 싱글 톤도 필요하지 않습니다. 컨테이너가 그것을 처리 할 것입니다.

@Stateless 
public class UserDAO { 

    @PersistenceContext(unitName="AddUsersPU") 
    private EntityManager mEM; 

그리고 @EJB 주석

@EJB 
private UserDAO userDao; 

를 사용하여 EJB를 주입하면, 점에서 EM을 설정해야하고, 그나마 것, 즉.의

public void setEM(EntityManager em)` 

방법을 모두 제거되어

+0

충분히 간단하지만 내가 이것을 시도 할 때 NullPointerException을 얻는다. 내 추측은 UserDAO 자신 (?)을 생성했기 때문에 컨테이너가 EntityManager를 주입하지 않는 것 같다. (위의 내 SomeApplicationManager에서 수행합니다.) @Stateless UserDAO에 대한 참조를 직접 만들지 않고도 얻을 수있는 방법이 있습니까? –

+0

예, @EJB를 사용하십시오. 편집보기 –