2015-09-17 6 views
0

У меня есть вопрос, можно ли использовать java CDI в конверте JPA?CDI Inject Class в конвертере JPA (EclipseLink)

Я делаю некоторые тесты для изучения, и я не в состоянии вводить объекты в пределах моего преобразователя:

Я использую EclipseLink, смотрите мой код, пожалуйста, анализировать мой код, где я неправильно ? И как я могу сделать это наилучшим образом?

В принципе, для лучшего понимания у меня будет сеансовый компонент, представляющий мой пользователь, входящий в систему, этот сеанс Bean У меня есть User TimeZone, я бы хотел ввести этот часовой пояс в My Converter, чтобы записать данные в 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(); 
} 
} 

Примечание: Вне инъекции в конвертер, все остальные функции работают отлично, Я могу изгнать EntityManager и другие классы, а также сохранить данные в базе данных

ответ

2

К сожалению, вы не можете. Специфические мандаты поддерживают инъекцию CDI в реализациях EntityListener. Он не применялся к преобразователям.

Если вы хотите получить доступ к своим точкам инъекции, вы можете использовать CDI.current(), чтобы получить доступ к экземпляру CDI<Object>. Используя это, как с помощью Instance<Object>, вы можете сделать такие вещи, как .select(qualifier).select(clazz).get(), чтобы получить экземпляр компонента.

Если вам нужно использовать квалификатор, вам потребуется буквальный первый.

public class UserTimeZoneQualifierLiteral extends AnnotationLiteral<UserTimeZoneQualifier> implements UserTimeZoneQualifier { 

} 

Затем экземпляр

UserTimeZoneQualifier qualifier = new UserTimeZoneQualifier(); // or use a singleton here. 
+0

Не мог бы вы направить меня на путь, чтобы сделать то, что я хочу? Как я могу работать с пользовательским часовым поясом, зарегистрированным для преобразования или JPA-объекта? И большое спасибо за расширенную поддержку –

+0

Я просто добавил некоторую информацию в свой ответ, дайте мне знать, если это поможет. –

+0

Perfect I test: '' 'String userTimeZone = javax.enterprise.inject.spi.CDI.current(). Select (UserSession.class) .get(). GetTimeZoneLocale();' '' и он работал, я не мог делать с квалификатором, у вас есть пример? Я должен сделать некоторый класс, который расширяет класс AnnotationLiteral? –

Смежные вопросы