我有一个 Java 应用程序,它有一个用 Swing 制作的 GUI,并且可以互换使用两个数据库。两个数据库之一是 mongoDB,另一个是 MySQL。使用命令行选项选择要使用的数据库。对于 MySQL 数据库,我也使用 Hibernate 和 JPA。我的代码如下所示:
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import java.awt.EventQueue;
import java.util.concurrent.Callable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Command(mixinStandardHelpOptions = true)
public class App implements Callable<Void> {
private static final Logger LOGGER = LogManager.getLogger(App.class);
@Option(names = { "--database" }, description = "'mongo' or 'mysql'")
private String databaseType = "mysql";
public static void main(String[] args) {
new CommandLine(new App()).execute(args);
}
@Override
public Void call() throws Exception {
EventQueue.invokeLater(() -> {
switch (databaseType) {
case "mysql":
EntityManagerFactory emf;
EntityManager entityManager;
try {
emf = Persistence.createEntityManagerFactory("name");
entityManager = emf.createEntityManager();
// other stuff
} catch (Exception e) {
LOGGER.log(Level.ERROR, "MySQL Exception", e);
}
break;
case "mongo":
// mongo stuff, no EntityManagerFactory here
break;
default:
LOGGER.log(Level.ERROR, "--database must be either 'mysql' or 'mongo'");
System.exit(1);
}
//...
try {
View view = new View();
view.setVisible(true);
} catch (Exception e) {
LOGGER.log(Level.ERROR, "Exception", e);
}
});
return null;
}
如果mysql
我正在创建一个EntityManagerFactory
和一个EntityManager
. 这里entityManager
创建的作为参数传递给存储库的构造函数,并在应用程序的整个生命周期中使用。我想知道关闭entityManager
和工厂的最佳做法是什么。在文档中搜索我发现了这个:
关闭 EntityManagerFactory 不应掉以轻心。长期保持工厂开工比反复创建和关闭新工厂要好得多。因此,大多数应用程序永远不会关闭工厂,或者仅在应用程序退出时关闭它。
所以我想知道,在应用程序关闭时关闭工厂和实体管理器与不关闭它有什么区别?同样在我的情况下,我声明emf
并entityManager
在mysql
案例内部,因为mongodb
. 为了在应用程序关闭时关闭它们,我应该怎么做?我发现了一些关于Runtime.getRuntime().addShutdownHook()
. 我尝试像下面的代码一样使用它,但它似乎不起作用。
try {
emf = Persistence.createEntityManagerFactory("name");
entityManager = emf.createEntityManager();
Thread closeHook = new Thread(() -> {
if (emf != null) {
entityManager.close();
emf.close();
LOGGER.log(Level.INFO, "Close entity manager and entity manager factory");
}
});
Runtime.getRuntime().addShutdownHook(closeHook);
// other stuff
} catch (Exception e) {
LOGGER.log(Level.ERROR, "MySQL Exception", e);
}