I need to check, create and store a property at Application start (in applicationStarted()) - but I cannot write this to the database as the Persistence says there is no security context and I cannot save the change in local.app.properties as it does not persist pass a reboot.
OK, please can you close this question, as I have found a way to do what I need.
I needed to create/update an entity value from the applicationStarted function of my implementation of the AppContext.Listener class. The problem was with the entityManager, I could not ‘persist’ the change as there was no security context at this stage. To get round this, I create a sql statement and use the entityManager to create a native query and executeUpdate, i.e.
To associate a security context with the current thread you can use the Authentication interface or the @Authenticated annotation.
An example of creating a user on the server startup:
package com.company.appstart;
import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.Transaction;
import com.haulmont.cuba.core.TypedQuery;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.core.global.PasswordEncryption;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.security.app.Authentication;
import com.haulmont.cuba.security.entity.Group;
import com.haulmont.cuba.security.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.UUID;
@Component("app_Bootstrap")
public class Bootstrap implements AppContext.Listener {
private Logger log = LoggerFactory.getLogger(getClass());
@Inject
private Persistence persistence;
@Inject
private Metadata metadata;
@Inject
private PasswordEncryption passwordEncryption;
@Inject
protected Authentication authentication;
@PostConstruct
public void init() {
AppContext.addListener(this);
}
@Override
public void applicationStarted() {
log.info("Checking existence of the 'system' user");
authentication.begin();
try {
try (Transaction tx = persistence.createTransaction()) {
TypedQuery<User> query = persistence.getEntityManager().createQuery(
"select u from sec$User u where u.login = ?1", User.class);
query.setParameter(1, "system");
User user = query.getFirstResult();
if (user == null) {
log.info("User 'system' does not exist, creating it");
user = metadata.create(User.class);
user.setLogin("system");
user.setPassword(passwordEncryption.getPasswordHash(user.getId(), "1"));
user.setGroup(persistence.getEntityManager().getReference(
Group.class, UUID.fromString("0fa2b1a5-1d68-4d69-9fbd-dff348347f93")));
persistence.getEntityManager().persist(user);
} else {
log.info("User 'system' already exists");
}
tx.commit();
}
} finally {
authentication.end();
}
}
@Override
public void applicationStopped() {
}
}