2012-03-20 15 views
14

Ho provato a utilizzare lo DataTime nella mia classe entity. Aggiungendo @Temporal(TemporalType.DATE) sopra il campo, ho ricevuto l'errore dicendo "Il campo o proprietà persistente per un tipo temporale deve essere di tipo java.util.Date, java.util.Calendar o java.util.GregorianCalendar". Posso introdurre la conversione avanti e indietro; utilizzando setter e getter come segue:Come utilizzare il tempo joda con JPA (eclipselink)?

@Temporal(TemporalType.DATE) 
private Calendar attendanceDate; 

public DateTime getAttendanceDate() { 
    return new DateTime(this.attendanceDate); 
} 

public void setAttendanceDate(DateTime attendanceDate) { 
    this.attendanceDate = attendanceDate.toCalendar(Locale.getDefault()); 
} 

ma spero eclipselink di farlo per me. Sono andato attraverso 'Persist Joda-time's DateTime via Hibernate. La risposta suggerisce di usare l'ibernazione, ma devo usare eclipselink. Posso usare l'oggetto DateTime nella mia classe di entità con rappresentazione DB come BLOB, ma ho bisogno di esso come Date. C'è qualcosa come jodatime-eclipselink? O qualche altro suggerimento? Grazie per l'aiuto.

risposta

15

base il link definisce un convertitore EclipseLink convertire da Joda DateTime a java.sql.Timestamp o Data. È possibile utilizzarlo o definire il proprio convertitore e utilizzarlo tramite @Convert, @Converter in EclipseLink.

Per la creazione DDL, il convertitore deve definire il metodo di inizializzazione e impostare il tipo nel campo della mappatura su java.sql.Timestamp.

Si prega di registrare un bug (o votare per quello esistente) su questo in EclipseLink, dovremmo avere il supporto per Joda.

+0

Per quanto riguarda la creazione DDL, nel mio metodo di inizializzazione ho questo: mapping.getField() .setSqlType (java.sql.Types.TIMESTAMP); Tuttavia, il tipo che è stato creato nel mio db è varchar (255). Qualunque idea del problema potrebbe essere? –

+5

@kaciula Ho avuto modo di farlo aggiungendo questo : 'mapping.getField(). setType (java.sql.Timestamp.class);'. HTH. –

0
+3

Sebbene ciò possa teoricamente rispondere alla domanda, [sarebbe preferibile] (http://meta.stackexchange.com/q/8259) includere qui le parti essenziali della risposta e fornire il collegamento per riferimento. – oers

+0

Ho trovato un file jar e ha meno informazioni. Dovrei usare l'unica classe del convertitore all'interno del file jar? Grazie per l'aiuto! – Ahamed

+0

Still JPA creerà una colonna come 'BLOB' non come' DATE' :( – Ahamed

2

Ahamed, hai detto che non funzionava per te. Inoltre, è necessario eseguire l'override del metodo di inizializzazione del convertitore per definire il tipo di campo desiderato:

@Override 
public void initialize(DatabaseMapping mapping, Session session) { 
    ((AbstractDirectMapping) mapping) 
      .setFieldClassification(java.sql.Timestamp.class); 
} 
4

ho voluto fare la stessa cosa, e Googling intorno in realtà mi ha portato qui. Sono riuscito a farlo usando l'annotazione @Access. Innanzitutto, annoti la classe

@Access(AccessType.FIELD) 
public class MyClass 
{ 
    .... 

Ciò fornisce l'accesso al campo a tutto ciò in modo che non sia necessario annotare i campi singolarmente. Quindi si crea un getter and setter per l'uso del JPA.

@Column(name="my_date") 
@Temporal(TemporalType.DATE) 
@Access(AccessType.PROPERTY) 
private Date getMyDateForDB() 
{ 
    return myDate.toDate(); 
} 

private void setMyDateForDB(Date myDateFromDB) 
{ 
    myDate = new LocalDate(myDateFromDB); 
} 

Il @Access(AccessType.PROPERTY) dice a JPA di persistere e recuperare tramite questi metodi.

Infine, ti consigliamo di contrassegnare la variabile membro come transitoria come segue

@Transient 
private LocalDate myDate = null; 

Ciò arresta JPA dal tentativo di persistere dal campo pure.

Questo dovrebbe portare a termine quello che stai cercando di fare. Ha funzionato benissimo per me.

+0

Come possiamo accedere a 'myDate' a livello di servizio (DAO)? Non può avere un mutatore e un accessorio (sono privati anche per 'myDateForDB'). – Tiny

+0

Non sono sicuro di comprendere appieno la tua domanda.Puoi avere un getter pubblico e un setter per' LocalDate myDate'. Poiché la classe è annotata con '@Access (AccessType.FIELD)' JPA non guarderà affatto il getter e il setter . – dnc253

6

provo uso Joda-tempo-EclipseLink-integrazione, ma non funzionano, problably ho fatto qualcosa di sbagliato,

Così ho fatto più Ricerche da e ho trovato questo link http://jcodehelp.blogspot.com.br/2011/12/persist-joda-datetime-with-eclipselink.html, usano @Converter annotazione per la conversione il tempo di data di Joda.

I Prova e lavora per me, spero, lavori anche per te.

+1

+1: questo link lo spiega con grande dettaglio :) –

1

Il seguente è un esempio di lavoro sulla base delle risposte disponibili per l'argomento

In sostanza l'approccio più semplice è quello di utilizzare EclipseLink @Converter per un campo DateTime nella vostra Entità.

L'utilizzo convertitore appare come segue:

import org.eclipse.persistence.annotations.Convert; 
import org.eclipse.persistence.annotations.Converter; 
import javax.persistence.*; 
import org.joda.time.DateTime; 

@Entity 
public class YourEntity { 

    @Converter(name = "dateTimeConverter", converterClass = your.package.to.JodaDateTimeConverter.class) 
    @Convert("dateTimeConverter") 
    private DateTime date; 

E il convertitore stesso:

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 java.sql.Timestamp; 

public class JodaDateTimeConverter implements Converter { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public Object convertDataValueToObjectValue(Object dataValue, Session session) { 
     return dataValue == null ? null : new DateTime(dataValue); 
    } 

    @Override 
    public Object convertObjectValueToDataValue(Object objectValue, Session session) { 
     return objectValue == null ? null : new Timestamp(((DateTime) objectValue).getMillis()); 
    } 

    @Override 
    public void initialize(DatabaseMapping mapping, Session session) { 
     // this method can be empty if you are not creating DB from Entity classes 
     mapping.getField().setType(java.sql.Timestamp.class); 
    } 

    @Override 
    public boolean isMutable() { 
     return false; 
    } 

} 

sto aggiungendo questo al fine di facile copia-e-incolla soluzione.

0

La risposta da Atais funziona bene. Di seguito un aggiornamento ad esso.

È possibile omettere l'annotazione @converter registrandola globalmente. A persistance.xml in persitence unità aggiungono:

<mapping-file>META-INF/xyz-orm.xml</mapping-file> 

e il file META-INF/xyz-orm.xml con i contenuti:

<?xml version="1.0"?> 
<entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm" version="2.1"> 
    <converter class="pl.ds.wsc.storage.converter.JodaDateTimeConverter"/> 
</entity-mappings> 

Se il file di configurazione è META-INF/orm.xml allora si può omettere anche primo passo, perché è di default per confing tutte le unità di persistenza.

Problemi correlati