user_mda
user_mda

Reputation: 19428

Dropwizard sessions at program run

I am trying to persist the time at which a dropwizard application starts.

public class Main Application extends Application<MainConfiguration> {
private final HibernateBundle<DeployerConfiguration> hibernate = new       HibernateBundle<AppConfiguration>(App.class) {

public DataSourceFactory getDataSourceFactory(
        AppConfiguration configuration) {
    return configuration.getDataSourceFactory();
}


    @Override
    public void initialize(Bootstrap<AppConfiguration> bootstrap) {
    bootstrap.addBundle(hibernate);

public static void main() {
   final AppDAO ddao = new AppDAO(hibernate.getSessionFactory());
   App app = new App(new Date());
  adao.create(app);

The Object:

JsonIgnoreProperties(ignoreUnknown = true)
@Entity
@Table(name = "app")

@NamedQuery(name = "App.findAll", query = "SELECT d FROM App d")

public class App implements  Serializable{

  private static final long serialVersionUID = 1L;
  AppDAO adao;
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  long id;


@JsonProperty
Date started;


public App ( Date started) {
    this.started = started;

}

The DAO object

 public class AppDAO extends  AbstractDAO<Appr>  {
 public SessionFactory sessionFactory;

 public AppDAO(SessionFactory sessionFactory) {
    super(sessionFactory);
 }

public Session session;
public App create(App app) {
  return persist(app);

}

When I try to save this object in the main() method, it complains that there is no session associated with the object. Upon debugging it gives the DAO object as null which is true because there is no user session created yet. In this case how do I persist an object? What am I missing

Upvotes: 1

Views: 2131

Answers (2)

EFreak
EFreak

Reputation: 3289

To add to the previous answer. I was unable to simply get it up and working with just the bind. The code also needs to be wrapped in a transaction in order for the persistence to work. (Correct me if I'm wrong here)

Here is a working code snippet.

  public User run() {
    Transaction transaction = null;
    try (Session session = sessionFactory.openSession()) {
      ManagedSessionContext.bind(session);
      transaction = session.beginTransaction();

      // This interacts with the DAO object
      final User user = userDao.findAgentSmith();

      commitTransaction(transaction);
      return user;
    } catch (Exception e) {
      rollbackTransaction(transaction);
      log.error("Unable to create admin user", e);
      throw new RuntimeException(e);
    } finally {
      ManagedSessionContext.unbind(sessionFactory);
    }
  }

  private void commitTransaction(Transaction txn) {
    if (txn != null && txn.getStatus().canRollback()) {
      txn.commit();
    }
  }

  private void rollbackTransaction(Transaction txn) {
    if (txn != null && txn.getStatus().canRollback()) {
      txn.rollback();
    }
  }

Without the transaction, the function returns successfully but it doesn't interact with the persistence layer.

Upvotes: 1

James Cube
James Cube

Reputation: 421

Dropwizard manages session automagically only if you are using DAO in resource method annotated as @UnitOfWork

Documentation here

If you want use DAO outside of this scope, you need to create and manage session manually, which is pretty simple :

Session session = hibernate.getSessionFactory().openSession();
ManagedSessionContext.bind(session);
//do your stuff....
session.close();

Upvotes: 6

Related Questions