CDI 在 JPA 转换器 (EclipseLink) 中注入 Class
CDI Inject Class in JPA Converter (EclipseLink)
我有一个问题,可以在 JPA 转换中使用 java CDI 吗?
我正在做一些测试来研究,但我无法在我的转换器中注入对象:
我正在使用eclipseLink,请查看我的代码,请分析我的代码哪里出错了?我怎样才能以最好的方式做到这一点?
基本上为了更好地理解,我将有一个代表我的用户登录的会话 bean,这个会话 Bean 我有用户时区,我想在我的转换器中注入这个时区将数据写入数据库
中的UTC
我的代码:
JPA转换器:org.eclipse.persistence.mappings.converters.Converter
package joda;
import inject.qualifier.UserTimeZoneQualifier;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import enumerator.UserType;
import security.UserSession;
@RequestScoped
public class JodaDateTimeUTCConverter implements Converter {
private static final long serialVersionUID = 1L;
// JUST TEST IT'S WAS INJECT AND REMOVE
private UserSession userSession = new UserSession("America/Mexico_City", UserType.HIGH_HISK);
@Inject
@UserTimeZoneQualifier
String userTimeZone;
//TODO FOR TEST
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss:SSS - z - ZZZZZZZZZZZZZZZZZZ");
SimpleDateFormat dt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS - z - ZZZZZZZZZZZZZZZZZZ");
@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
// TODO REMOVE
DateTimeZone timeZone = DateTimeZone.forID(userSession.getTimeZoneLocale());
System.out.println("BEFORE OF CONVERTION : " + dt.format(dataValue));
System.out.println("AFTER OF CONVERTION : " + dtf.print(new DateTime((Timestamp) dataValue).withZone(timeZone)));
System.out.println("userTimeZone INJECT" + userTimeZone);
return dataValue instanceof Date ? new DateTime((Timestamp) dataValue).withZone(timeZone) : null;
}
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
System.out.println("GO TO DB(DATAVALUE)");
System.out.println("AFTER OF CONVERTION : " + dtf.print(((DateTime) objectValue).withZone(DateTimeZone.UTC)));
return objectValue instanceof DateTime?((DateTime) objectValue).withZone(DateTimeZone.UTC).toLocalDateTime().toDate() : null;
}
@Override
public void initialize(DatabaseMapping mapping, Session session) {
}
@Override
public boolean isMutable() {
return false;
}
public String getUserTimeZone() {
return userTimeZone;
}
public void setUserTimeZone(String userTimeZone) {
this.userTimeZone = userTimeZone;
}
}
我的@UserTimeZoneQualifier:
package inject.qualifier;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface UserTimeZoneQualifier {
}
和我的 UserSessionProduce:
package inject;
import inject.qualifier.UserTimeZoneQualifier;
import javax.annotation.PostConstruct;
import javax.enterprise.inject.Produces;
import enumerator.UserType;
import security.UserSession;
public class UserSessionProduce {
private UserSession userSession;
@PostConstruct
public void init(){
this.userSession = new UserSession("America/Mexico_City", UserType.ADMINISTRATOR);
}
@Produces
public UserSession getUserSessionInstance(){
return this.userSession;
}
@Produces
@UserTimeZoneQualifier
public String getUserSessionTimeZone(){
return this.userSession.getTimeZoneLocale();
}
@Produces
public UserType getUserType(){
return this.userSession.getUserType();
}
}
注意: 除了注入 Converter 之外,所有其他功能都运行良好,我可以弹出 EntityManager 和其他 类 以及持久化数据在数据库中
很遗憾,你不能。该规范要求在 EntityListener
实现中支持 CDI 注入。它不适用于转换器。
如果您想访问注入点,可以使用 CDI.current()
来访问 CDI<Object>
实例。使用它就像使用 Instance<Object>
- 您可以执行 .select(qualifier).select(clazz).get()
之类的操作来检索 bean 实例。
如果需要使用限定符,首先需要一个字面量。
public class UserTimeZoneQualifierLiteral extends AnnotationLiteral<UserTimeZoneQualifier> implements UserTimeZoneQualifier {
}
然后实例化
UserTimeZoneQualifier qualifier = new UserTimeZoneQualifier(); // or use a singleton here.
我有一个问题,可以在 JPA 转换中使用 java CDI 吗?
我正在做一些测试来研究,但我无法在我的转换器中注入对象:
我正在使用eclipseLink,请查看我的代码,请分析我的代码哪里出错了?我怎样才能以最好的方式做到这一点?
基本上为了更好地理解,我将有一个代表我的用户登录的会话 bean,这个会话 Bean 我有用户时区,我想在我的转换器中注入这个时区将数据写入数据库
中的UTC我的代码:
JPA转换器:org.eclipse.persistence.mappings.converters.Converter
package joda;
import inject.qualifier.UserTimeZoneQualifier;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import enumerator.UserType;
import security.UserSession;
@RequestScoped
public class JodaDateTimeUTCConverter implements Converter {
private static final long serialVersionUID = 1L;
// JUST TEST IT'S WAS INJECT AND REMOVE
private UserSession userSession = new UserSession("America/Mexico_City", UserType.HIGH_HISK);
@Inject
@UserTimeZoneQualifier
String userTimeZone;
//TODO FOR TEST
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss:SSS - z - ZZZZZZZZZZZZZZZZZZ");
SimpleDateFormat dt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS - z - ZZZZZZZZZZZZZZZZZZ");
@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
// TODO REMOVE
DateTimeZone timeZone = DateTimeZone.forID(userSession.getTimeZoneLocale());
System.out.println("BEFORE OF CONVERTION : " + dt.format(dataValue));
System.out.println("AFTER OF CONVERTION : " + dtf.print(new DateTime((Timestamp) dataValue).withZone(timeZone)));
System.out.println("userTimeZone INJECT" + userTimeZone);
return dataValue instanceof Date ? new DateTime((Timestamp) dataValue).withZone(timeZone) : null;
}
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
System.out.println("GO TO DB(DATAVALUE)");
System.out.println("AFTER OF CONVERTION : " + dtf.print(((DateTime) objectValue).withZone(DateTimeZone.UTC)));
return objectValue instanceof DateTime?((DateTime) objectValue).withZone(DateTimeZone.UTC).toLocalDateTime().toDate() : null;
}
@Override
public void initialize(DatabaseMapping mapping, Session session) {
}
@Override
public boolean isMutable() {
return false;
}
public String getUserTimeZone() {
return userTimeZone;
}
public void setUserTimeZone(String userTimeZone) {
this.userTimeZone = userTimeZone;
}
}
我的@UserTimeZoneQualifier:
package inject.qualifier;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface UserTimeZoneQualifier {
}
和我的 UserSessionProduce:
package inject;
import inject.qualifier.UserTimeZoneQualifier;
import javax.annotation.PostConstruct;
import javax.enterprise.inject.Produces;
import enumerator.UserType;
import security.UserSession;
public class UserSessionProduce {
private UserSession userSession;
@PostConstruct
public void init(){
this.userSession = new UserSession("America/Mexico_City", UserType.ADMINISTRATOR);
}
@Produces
public UserSession getUserSessionInstance(){
return this.userSession;
}
@Produces
@UserTimeZoneQualifier
public String getUserSessionTimeZone(){
return this.userSession.getTimeZoneLocale();
}
@Produces
public UserType getUserType(){
return this.userSession.getUserType();
}
}
注意: 除了注入 Converter 之外,所有其他功能都运行良好,我可以弹出 EntityManager 和其他 类 以及持久化数据在数据库中
很遗憾,你不能。该规范要求在 EntityListener
实现中支持 CDI 注入。它不适用于转换器。
如果您想访问注入点,可以使用 CDI.current()
来访问 CDI<Object>
实例。使用它就像使用 Instance<Object>
- 您可以执行 .select(qualifier).select(clazz).get()
之类的操作来检索 bean 实例。
如果需要使用限定符,首先需要一个字面量。
public class UserTimeZoneQualifierLiteral extends AnnotationLiteral<UserTimeZoneQualifier> implements UserTimeZoneQualifier {
}
然后实例化
UserTimeZoneQualifier qualifier = new UserTimeZoneQualifier(); // or use a singleton here.