简体   繁体   中英

Best way to interact with EJBs in Java EE

I have a moderate sized Java EE 6 project that uses several EJBs, including one which sole purpose is managing database calls through JPA. My question is what is the best way to add a new class that does some random bit of functionality and then calls the database access EJB to persist the data from this class.

Does this new class have to be an EJB if it needs access to annotations and injections? Does it have to be an EJB if it has to be deployed with the rest of the project?

I was told that if you want to add a new logic class to the project it either has to be an EJB or you can remotely integrate it using JNDI to access EJB elements and create some kind of client interface. Right now my new class is just a POJO but it's not able to access the EJB functionality.

What should I do in general?

EDIT: Please note my question IS NOT about database access. That's just an example I'm using. My guestion is more broad. I want to know how to access EJB methods from other classes I create. From one EJB to another you can simply inject the other EJB since they're both container managed. But say I create another class in the same package as the EJBs how might How can I access those methods? Is it possbile? What is the best practices here.

Right now I have a class that is taking twitter feed data from a URL it then parses the JSON and returns a string of the top 10 entries. I want to call my EJB that manages database access and pass that string to its corresponding method but I cannot do that because my class is not also an EJB.

EJBs are generally used to implement services of any kind. They integrate really well with JPA so are often used for DB access, but that's not their only usage.

What EJBs are typically not suited for is modeling data. Ie they should be the verbs in your application, not the nouns. The following is thus wrong :

@Stateless
@Entity
public class CreditCard { // silly, don't do this!

     @Id
     Long id; + getters/setters
     Data expiration date; + getters/setters
}

The following is better, it's a service that when your application starts up fetches some quote data from somewhere:

@Singleton
@Startup
public class QuoteFetcher {

     private List<Quote> quotes; // + getter

     @PostConstruct
     public fetchQuote()
          quotes = SomeUrlBuilder.someUrl().getQuotes();
     }
 }

The following is the obligatory DAO example:

@Stateless
public class JPAInvoiceDAO implements InvoiceDAO {

     @PersistenceContext
     private EntityManager entityManager;

     public Invoice getById(Long invoiceId) {
           return entityManager.find(invoiceId, Invoice.class);
     }

     // More DAO methods
}

The following shows how declarative security is used, and how a bean looks up something that has been externally mapped into its private context (ENC):

@Stateless
public class TokenFetcher

    @Resource
    private SessionContext sessionContext;

    @RolesAllowed("SYSTEM")
    public Token getToken() {
        return (Token) sessionContext.lookup("token");
    }
}

The second part of the question seems to be how to use these beans in your code. There are basically four methods:

  1. Injection in managed beans
  2. Bootstrapping via JNDI
  3. Automatically called at startup
  4. Automatically via a timer

Injection is the easiest way, but only managed beans are injection candidates (basically meaning the Java EE framework creates the bean, and you don't use new() to instantiate it).

Eg Injection:

@ManagedBean
public class InvoiceBacking {

     private Long invoiceId; // + getter/setter
     private Invoice invoice; // + getter

     @EJB
     private InvoiceDAO invoiceDAO;

     @PostConstruct
     public void init() {
          invoice = invoiceDAO.getById(invoiceId);
     }
 }

(also see Communication in JSF 2.0#Processing GET request parameters )

Bootstrapping via JNDI:

 public class SomeQuartzJob implements Job {

     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
          InvoiceDAO invoiceDAO = (InvoiceDAO) new InitialContext().lookup("java:global/myApp/myEJB/InvoiceDAO");
          List<Invoice> openInvoices = invoiceDAO.getAllByOpenStatus();
          // verbose exception handling and closing JNDI context omitted for brevity
     }
  }

The @Singleton bean showed earlier was an example of how the Java EE framework calls your code itself at startup. For the automatic timer you would use the @Schedule annotation on a bean's method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM