0

For some reason the EntityManager isn't being injected into a separate thread that I want to keep running in the background. Other classes can access the entity manager without a problem, but those aren't running in a separate thread.

What am I doing wrong here?

@Stateful
public class DatabaseManager extends Thread{
    @PersistenceContext(unitName="imas-unit")
    private EntityManager em;


    private int timeBetweenRefresh;

    public void run(){
        loadProperties();
        retrieveDBContent();
        long timerTicks = System.currentTimeMillis();
        while(running){
            if(System.currentTimeMillis() > timerTicks + timeBetweenRefresh){
                timerTicks = System.currentTimeMillis();
                deleteAllRecords();
                retrieveDBContent();
            }
            Thread.sleep(1000);
        }
    }

    private void deleteAllRecords(){
        //Deletes all the records
    }

    private void loadProperties(){
        //Loads properties for methods
    }

    private void retrieveDBContent(){
        List<Cel> celList = methodThatGetsCells();
        System.out.println("Saving to database");
        for(Cel cell : celList){
            try{
                em.persist(cell); //Null pointer here
                em.flush();
            }
                catch(Exception e){
                    System.out.println(e.getMessage());
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            System.out.println("Retrieval failed. Please check error log for further information.");
            e1.printStackTrace();
        }
    }

}

I can post more information if needed.

Strike08
  • 257
  • 1
  • 2
  • 16

1 Answers1

1

I feel that you're thinking about this a bit wrong. The container is going to take out your Stateless bean when it thinks it's done - it doesn't know you spun off a thread.

I would look at using the @Schedule annotation and, perhaps, @Singleton. It looks like you're doing some DB maintenance periodically and you likely don't want more than one bean doing that. So something more like:

@Singleton
public class DatabaseManager {
    @PersistenceContext(unitName="imas-unit")
    private EntityManager em;

    ...

    @Schedule(minute = "*", persistent = false)
    private void yourMaintenanceMethod() {
    ...

The method "yourMaintenanceMethod" would, in this example get run every minute. You can put in a seconds field to run, for example, every 15 seconds or whatever you need.

I've used this pattern successfully in the past for similar types of things - it basically lets the container do the threading and ultimately simplifies your code a bit.

stdunbar
  • 10,999
  • 9
  • 26
  • 38