- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我试图使用持久性和 servlet guice 扩展,让简单的 webapp 在 Jetty 上与 Guice 和 JPA 一起工作。
我写了这个服务实现类:
lớp công khai PersonServiceImpl triển khai PersonService {
private EntityManager em;
@Inject
public PersonServiceImpl(EntityManager em) {
this.em = em;
}
@Ghi đè
@Giao dịch
public void savePerson(Person p) {
em.persist(p);
}
@Ghi đè
public Person findPerson(long id) {
return em.find(Person.class, id);
}
@Ghi đè
@Giao dịch
public void deletePerson(Person p) {
em.remove(p);
}
这是我的 servlet(用@Singleton 注释):
@Inject
PersonService personService;
@Ghi đè
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name");
String password = req.getParameter("password");
String email = req.getParameter("email");
int age = Integer.valueOf(req.getParameter("age"));
Person p = new Person();
p.setAge(age);
p.setName(name);
p.setEmail(email);
p.setPassword(password.toCharArray());
logger.info("saving person");
personService.savePerson(p);
logger.info("saved person");
logger.info("extracting person");
Person person = personService.findPerson(p.getId());
resp.getWriter().print("Hello " + person.getName());
}
当我运行它时,它起作用了,我得到了发送给客户端的名称,但是当我查看日志时,我发现没有为插入生成 DML,并且从 postgresql 中选择不返回任何结果,这意味着它并没有真正持久化。
我调试了代码,我看到了 JpaLocalTxnInterceptor
称为 txn.commit()
.
然后我修改了PersonServiceImpl
并使用 Provider
而不仅仅是 Quản lý thực thể
它按预期工作。现在我真的不明白为什么,这可能是因为我不太理解 Provider 背后的想法。关于Guice wiki page它说:
Note that if you make MyService a @Singleton, then you should inject Provider instead.
但是,我的 PersonServiceImpl 不是 @Singleton,所以我不确定它为什么适用,也许是因为 Servlet?
如果您能帮我解决这个问题,我将不胜感激。
câu trả lời hay nhất
你需要Provider
因为 Guice 的内置持久性和 servlet 扩展期望 EntityManager 是请求范围的。通过从保存在单例 servlet 中的服务中注入(inject)请求范围的 EntityManager,您将进行范围扩大的注入(inject),并且 Guice 不会存储来自陈旧的、不匹配的 EntityManager 的数据。
Provider 是一个单方法接口(interface),它公开了一个 lấy()
方法。如果你注入(inject) Provider
然后调用lấy()
,它将返回一个实例,其创建方式与您直接注入(inject) Foo 的方式相同。 但是,注入(inject) Provider 允许您控制创建的对象数量和创建时间。 This can be useful in a few cases:
用于绑定(bind) X
, Provider
, hoặc @Provides X
, Guice 会自动允许你注入(inject) X
hoặc Provider
直接地。您可以在不调整任何绑定(bind)的情况下使用 Providers,并且 Providers 可以很好地与 binding annotations 配合使用.
广义上讲,scopes定义对象的生命周期。默认情况下,Guice 为每次注入(inject)创建一个新对象;通过将对象标记为@Singleton,您可以指示 Guice 为每次注入(inject)注入(inject)相同的实例。 Guice 的 servlet 扩展还支持 @RequestScoped 和 @SessionScoped 注入(inject),这会导致在一个请求(或 session )中一致地注入(inject)相同的对象,但为不同的请求(或 session )注入(inject)新的对象。 Guice 还允许您定义自定义范围,例如 thread scope (每个线程一个实例,但同一线程中的跨注入(inject)实例相同)。
@Singleton public class YourClass {
@Inject HttpServletRequest request; // BAD IDEA
}
如果直接从 @Singleton 组件中注入(inject)请求范围的对象会发生什么?创建单例时,它会尝试注入(inject)与当前请求相关的实例。请注意,可能没有当前请求,但如果有一个,该实例将保存到单例中的一个字段中。随着请求的来来去去,永远不会重新创建单例,也永远不会重新分配该字段——因此在第一个请求之后,您的组件将停止正常工作。
将窄范围对象 (@RequestScoped) 注入(inject)宽范围对象 (@Singleton) 称为范围扩大注入(inject)。并非所有扩大范围的注入(inject)都会立即显示症状,但所有注入(inject)都可能在以后引入挥之不去的错误。
PersonService 没有用@Singleton 注释,但是因为您在@Singleton servlet 中注入(inject)和存储一个实例,所以它本身也可能是一个单例。这意味着 EntityManager 也有单例行为,原因相同。
theo the page you quoted , EntityManager 是短暂的,只为 session 或请求而存在。这允许 Guice 在 session 或请求结束时自动提交事务,但重复使用相同的 EntityManager 可能会阻止在第一次之后的任何时间存储数据。切换到提供者允许您通过在每个请求上创建一个新的 EntityManager 来缩小范围。
(您也可以将 PersonService 设为 Provider,这也可能会解决问题,但我认为最好遵循 Guice 的最佳实践并使用 Provider 明确缩小 EntityManager 的范围。)
关于java - Guice Provider
正在复制的问题是,当sew呈现登录页面时,然后我们继续执行身份验证,现在将我们重定向到网站的仪表板,此时我们继续关闭会话,并且在之前的交互中生成的这些cookie没有被删除。这个问题是重复性的,并且一
我是 Flutter 的新手,目前正在研究 DI。 我正在使用 flutter_bloc 和 provider 包。 flutter_bloc 附带一个 RepositoryProvider,我现在问
我是 Flutter 的新手,目前正在研究 DI。 我正在使用 flutter_bloc 和 provider 包。 flutter_bloc 附带一个 RepositoryProvider,我现在问
我正在使用 Angular2 开发一个应用程序。 我正在尝试在我的应用程序中使用 Reactive Forms,但我遇到了一些错误: 第一个错误是关于 NgControl 的,如下所示: No pro
最近很多用户在使用电脑的时候发现了wmi provider host进程占用内存比较大,不知道这个进程到底是干什么的,能不能禁止,怎么禁止。下面来一起看看想想的介绍吧。 wmi provide
我的问题是: 当我在设计时不知道这些表达式的数量和类型时,如何将列表中的表达式拼接成一个引用? 在底部,我包含了类型提供程序的完整代码。 (我已经剥离了这个概念来证明这个问题。)我的问题出现在这些行:
我目前正在学习使用 Flutter 进行应用程序开发,并已开始学习 Provider 包。我遇到了一些困难并收到错误: “在此...小部件之上找不到正确的提供者” 我最终移动了 Provider 小部
我是 android 的新手,我正在学习如何使用 JavaMail API 发送电子邮件的教程,我已经正确添加了必要的 Jar,但我总是遇到无法解析 GmailSender 类上的符号提供程序,我尝试
我正在我的 Angular 应用程序中进行单元测试,我正在使用 TestBed 方法, 我正在测试组件,所以每个规范文件看起来像这样 import... describe('AppComponent'
enter image description here 代码:这是我的 index.js 文件 index.js import { Provider } from "react-redux"
Microsoft ASP.NET Universal Providers 1.1昨天与System.Web.Providers 1.2一起发布.在后面的 nuget 页面上声明:Legacy pac
在我的 Next js 项目中,我使用了 Next auth,其中 import {Provider} from 'next-auth/client' , 并包裹 在 _app.js 中。 但是,与此
当我在 View 模型中使用如下界面时 class MainViewModel @ViewModelInject constructor( private val trafficImagesR
更新 - 我实际上发现它是 Flutter Issue . 我有两个 Provider,一个是 EntriesProvider,另一个是 EntryProvider。我在创建条目时使用我的 Entry
function configure($provide, $injector) { $provide.provider("testservice", function () {
这真让我抓狂。我似乎无法弄清楚这有什么问题。 代码: public interface IMinutesCounter { void startTimer(); void stopTi
我在我的项目中玩 Dagger 2,然后我陷入了这个错误编译。-> Error:(18, 21) error: ....MyManager cannot be provided without an
我有一个 Resteasy 应用程序,它使用 Spring 并包含 ContainerRequestFilter 和 ContainerResponseFilter 实现,并用 @Provider 注
我正在尝试使用 Dagger2 设置一个新项目,我以前使用过 Dagger2,但现在我正在尝试自己从头开始设置它。我正在从我参与的 Kotlin 项目中获取示例,但无法像现在在 Kotlin 中一样为
我刚开始学习 dagger2,遇到了一个奇怪的问题,在我看来像是一个错误。这是模块: @Module public class SimpleModule { @Provides Coo
Tôi là một lập trình viên xuất sắc, rất giỏi!