我来自Spring阵营,我不想使用Spring,并且正在迁移到JavaEE6,但我测试DAO + JPA有问题,这是我的简化示例:
public interface PersonDao
{
public Person get(long id);
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常基本的DAO,因为我来自Spring,我相信DAO仍然有它的价值,所以我决定添加一个DAO层.
public class PersonDaoImpl implements PersonDao , Serializable
{
@PersistenceContext(unitName = "test", type = PersistenceContextType.EXTENDED)
EntityManager entityManager ;
public PersonDaoImpl()
{
}
@Override
public Person get(long id)
{
return entityManager .find(Person.class , id);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个JPA实现的DAO,我希望EE容器或测试容器能够注入EntityManager(就像Spring一样).
public class PersonDaoImplTest extends TestCase
{
@Inject
protected PersonDao personDao;
@Override
protected void setUp() throws Exception
{
//personDao = new PersonDaoImpl();
}
public void testGet()
{
System.out.println("personDao = " + personDao); // …Run Code Online (Sandbox Code Playgroud) 我正在使用带有CDI的JBoss 7.1.1.
我在JNDI中有一个名为ServiceAccount的无状态bean.这是真正的服务实现.我有另一个名为ServiceAccountMock的Statelss bean,它是一个Mock服务.两者都来自同一个界面,并打包在service.ear中.
我想要做的是在bean.xml中声明模拟服务作为替代,重新部署我的服务,然后所有客户端都看到模拟版本(在客户端没有改变任何东西).
当我部署我的service.ear时,JBoss说:
java.lang.IllegalArgumentException: JBAS011046: A component named 'ServiceAccount' is already defined in this module
Run Code Online (Sandbox Code Playgroud)
这是事实,两种服务都以相同的方式声明(@Stateless(name ="ServiceAccount")).
如果我更改模拟版本的名称,我必须在客户端更改使用哪个EJB(我不想这样做).
有谁知道这是怎么做到的吗 ?
在Web App中,需要通过每页JSF显示6个对象(表DB的行)的视图.为了进入下一个视图,将显示另一个不同的随机6个对象,依此类推......
所以我在具有思维@Singleton,查询与该表中的所有行@Schedule在给定的时间间隔工作,比方说,每隔1小时.它将有一个getCollection()方法.
然后每个访问者都会有一个@SessionScoped CDI bean,它将查询@Singleton的Collection ,然后将其随机播放以对特定用户进行随机查看.
与许多访问一样,将创建许多将同时访问getCollection()方法的CDI bean.
这是正确的吗?这种情况需要任何特定的注释吗?这样做的其他任何方式?
----- UPDATE ---
与朋友沟通后,特意Luiggi门多萨,他们告诉我,在这里最好的办法是使用的Ehcache或类似的,而不是Singleon.我认为就是这样.
我有以下课程:
public class MyMap extends HashMap {
public MyMap () { }
some more methods...
}
@SessionScoped
public ProducerClass implements Serializable {
@Produces @MyItem HashMap<A,B> produceItems () { }
}
@Named
public ConsumerClass {
@Inject @MyItem HashMap<A,B> property;
}
@Retention(RUNTIME)
public @interface MyItem {
}
Run Code Online (Sandbox Code Playgroud)
我在MyMap和HashMap表单的ConsumerClass中得到错误的模糊注入点.
怎么会这样 ?我认为注入类是通过@MyItem注释给出的唯一.
我想将一个Singleton EJB注入到我的POJO类中.使用新的EJB 3.1规范,是否可以将EJB注入POJO?我知道在EJB 3.0中,@ EJB注释可用于注入EJB,但这对简单的POJO不起作用.
@javax.inject.Inject也不适合我.
还有一件事是,容器和非容器资源之间有什么区别?我如何实现它,我正在使用JBoss AS 7.1.1.
我无法在Resteasy中注入cdi bean.在调试时,它似乎总是显示空指针异常.即以下代码中的'jaxRsImpl'始终为null.我试图在jboss eap 6.2上运行
@Path("/jaxrs-service")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class JAXRSService {
@Inject
private JAXRSImpl jaxRsImpl;
@POST
@Path("/authenticate")
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticate(Credentials user) {
return jaxRsImpl.authenticate(user);
}
}
Run Code Online (Sandbox Code Playgroud)
而我打算注入的课程是
@RequestScoped
public class JAXRSImpl {
public Response authenticate(Credentials user) {
// Some logic
}
}
Run Code Online (Sandbox Code Playgroud)
由于我的应用程序是web,所以我在WEB-INF文件夹中添加了beans.xml
我的Initialiser看起来像
@ApplicationPath("/rest")
public class JAXRSInitializer extends Application {
private Set<Object> singletons = new HashSet<Object>();
private Set<Class<?>> classes = new HashSet<Class<?>>();
public JAXRSInitializer() {
singletons.add(new JAXRSService());
classes.add(JAXRSImpl.class);
}
@Override
public Set<Class<?>> getClasses() {
return classes;
}
@Override …Run Code Online (Sandbox Code Playgroud) 这是@ApplicationScoped在@SessionScopedbean中注入bean 的正确方法吗?这会导致我的应用程序作用域bean存储在每个用户的会话中吗?
我有一个应用程序范围的bean,它包含我们在所有系统用户之间共享的一些值,现在我需要在会话bean的方法中获取这些值.
在我的应用程序中,我发现我的CDI托管bean之间有很多共同的方法,所以遵循DRY原则我想创建一个包含这些方法的超类.然后我会有十几个子课程.
所以超类不是抽象的 - 它有足够的功能来自己编写一个有用的页面.所以我有:
@Named
@RequestScoped
public class BasicBacking {
Run Code Online (Sandbox Code Playgroud)
是否可以使用它:
@Named
@RequestScoped
public class SpecialBacking extends BasicBacking {
Run Code Online (Sandbox Code Playgroud)
没有任何问题?如果我更改范围,例如:
@Named
@ViewScoped
public class ViewBacking extends BasicBacking implements Serializable {
Run Code Online (Sandbox Code Playgroud)
CDI规范是否提到了这一点?我在这里遇到麻烦吗?
我浪费了很多时间尝试解决此发行者,但我在同一个地方。我怀疑我将CDI与EJB混合在一起。
问题仍然存在,仅删除不起作用。
Caused by: javax.persistence.TransactionRequiredException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:866)
at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:579)
at com.oki.scope.console.model.dao.GenericDAO.save(GenericDAO.java:29)
at com.oki.scope.console.model.dao.GenericConsoleDAO.save(GenericConsoleDAO.java:12)
at com.oki.scope.console.service.ServidorServiceImp.salvar(ServidorServiceImp.java:27)
at com.oki.scope.console.service.ServidorServiceImp$Proxy$_$$_WeldClientProxy.salvar(Unknown Source)
at com.oki.scope.console.managedBean.consulta.ServidorMB.salvar(ServidorMB.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.el.parser.AstValue.invoke(AstValue.java:292)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 40 more
Run Code Online (Sandbox Code Playgroud)
我的DAO
public class GenericDAO<T, K> {
protected EntityManager em;
private Class<T> entityClass;
public GenericDAO(Class<T> entityClass, EntityManager …Run Code Online (Sandbox Code Playgroud) 我遇到了以下问题.我正在使用的Weld实现CDI.
我发现如果服务注释了,@ApplicationScoped那么@PostConstruct在第一次使用服务之前不会调用section.这是一个重现此行为的代码:
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.spi.CDI;
public class TestCdi {
public static void main(String[] args) {
try (WeldContainer weldContainer = new Weld().containerId("test").initialize()) {
FooService fooService = CDI.current().select(FooService.class).get();
fooService.test();
System.out.println("Done");
}
}
@ApplicationScoped
public static class FooService {
@PostConstruct
public void init() {
System.out.println("Post construct");
}
public void test() {
System.out.println("test");
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果fooService.test();被注释,则FooService.init()不会被调用.但删除@ApplicationScoped它再次工作!
这对我来说似乎很奇怪,我无法找到和描述这种行为.
此外,规范javax.inject.Provider.get()说:
提供完全构造和注入的T实例.
那么,问题是什么?它是这样设计还是这个bug?对我来说更重要的是:如何绕过这个问题?我需要我的服务 …