1

I have a class that looks like this:

@Named
public class TableView {

    @PersistenceContext protected EntityManager   em;
    @Resource           protected UserTransaction utx;

And of course I can get an instance during the construction of my bean like this:

@Inject private TableView view;

I believe it is CDI that has the job of filling in the EntityManager and the UserTransaction. However, after my user class has been instantiated I sometimes want another instance of TableView so how do I get it? Obviously

TableView anotherView = new TableView();

won't work since em and utx will be null. So how do I get a new working instance with the injections performed?

AlanObject
  • 9,613
  • 19
  • 86
  • 142
  • 1
    This link might solve your problem.. http://stackoverflow.com/questions/25153624/how-to-instantiate-more-cdi-beans-for-one-class – Ankit Feb 13 '16 at 22:34
  • @Ankit that is interesting but doesn't quite do it. I'm looking for a run-time API to instantiate beans. – AlanObject Feb 14 '16 at 00:20
  • 1
    Interface [`Instance`](https://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/Instance.html) and method `get()`. `Instance tableViewInstance; TableView newInstance = tableViewInstance.get();` – Geinmachi Feb 14 '16 at 00:50
  • @Geinmachi That seems to be what I was looking for. I'll try it out. If you want to post that as an answer I'll mark it as such once I have verified. – AlanObject Feb 14 '16 at 02:33
  • 1
    What "user class"? ... but however, the fact that you need a EM and UT in your VIEW indicates a more basic design problem in your application to me. – stg Feb 14 '16 at 12:46
  • @Geinmachi please post your comment as an answer, so OP can accept it. – G. Demecki Feb 19 '16 at 15:19
  • @G.Demecki He said he will verify if it works. – Geinmachi Feb 19 '16 at 19:23
  • @Geinmachi Sorry for the delay. As it ended out I reorganized my classes in my application so I didn't need it, but I did verify that this technique works. And it is pretty well documented in the javadoc for the Instance interface as well. So yes you did have the answer. – AlanObject Feb 20 '16 at 06:56

1 Answers1

1

Instance interface should do what you need:

Instance<TableView> tableViewInstance;
TableView anotherView = tableViewInstance.get();

But as stated in the comments, your view should not have/be aware of transactions and entity manager.

Geinmachi
  • 1,251
  • 1
  • 8
  • 20
  • My TableView objects are stateful DAOs that provide methods to get lists of records out of the data base. State includes first record, query size, filters, sorts, etc. How is it supposed to build CriteriaQueries and run them without access to the EntityManager? Is there some rule I am not aware of with regard to JPA and CDI? – AlanObject Feb 20 '16 at 15:56
  • What do you mean "stateful DAO"? EJB `@Stateful`? Your TableView has `@Named` annotation, so isn't it bound to the `xhtml` page? If so then it is presentation layer and what you do in `TableView` (transactions and EM) should be done in business logic layer (EJB `@Stateless` or `@Stateful`) by delegation through dependency injection (`@Inject` or `@EJB`). – Geinmachi Feb 20 '16 at 16:23
  • This is JSF web app not EJB. The backing bean in injected into the JSF Servlet's context, and it in turn needs to inject data access objects of various kinds. – AlanObject Feb 20 '16 at 17:48