org.eclipse.persistence.exceptions.ConversionExcep

2019-09-13 01:24发布

问题:

I am a beginner of eclipselink and persistence, i am using @EmbeddedId like this with javafx properties....

@Entity
public class Inwards implements Serializable{
Destination id;
StringProperty orderName;
IntegerProperty orderNo;
ObjectProperty<LocalDate> orderDate;
BooleanProperty save;

public Inwards(){
    this.orderName = new SimpleStringProperty();
    this.orderNo = new SimpleIntegerProperty();
    this.orderDate = new SimpleObjectProperty<LocalDate>(LocalDate.of(2015, Month.MARCH, 5));
    this.save = new SimpleBooleanProperty();
}

public Inwards(Integer orderNo, LocalDate orderDate,String orderName){
    this();
    this.orderName.set(orderName);
    this.orderNo.set(orderNo);
    this.orderDate.set(orderDate);
}

@EmbeddedId
public Destination getId() {
    return id;
}

public void setId(Destination id) {
    this.id = id;
}

public StringProperty orderNameProperty(){
    return this.orderName;
}

public String getOrderName(){
    return orderName.get();
}

public void setOrderName(String orderName){
    this.orderName.set(orderName); 
}

public Integer getOrderNo() {
    return orderNo.get();
}

public void setOrderNo(Integer orderNo) {
    this.orderNo.set(orderNo);
}

public IntegerProperty orderNoProperty(){
    return this.orderNo;
}

public LocalDate getOrderDate() {
    return orderDate.get();
}

public void setOrderDate(LocalDate orderDate) {
    this.orderDate.set(orderDate); 
}

public ObjectProperty<LocalDate> orderDateProperty(){
    return this.orderDate;
}

public boolean isSave(){
    return save.get();
}

public void setSave(boolean save){
    this.save.set(save);
}

public BooleanProperty saveProperty() {
    return this.save;
}
}

Here is the embedded class...

@Embeddable
public class Destination implements Serializable {
StringProperty city;
StringProperty pincode;
IntegerProperty destId;

public Destination(){
    this.city = new SimpleStringProperty();
    this.pincode = new SimpleStringProperty();
    this.destId = new SimpleIntegerProperty();
}

public Destination(Integer destId,String city,String pincode){
    this();
    this.destId.set(destId);
    this.city.set(city);
    this.pincode.set(pincode);  
}

public IntegerProperty destIdProperty(){
    return destId;
}

public final Integer getDestId(){
    return destIdProperty().get();
}

public final void setDestId(Integer destId){
    destIdProperty().set(destId);
}

public StringProperty cityProperty(){
    return city;
}

public String getCity() {
    return cityProperty().get();
}

public void setCity(String city) {
    cityProperty().set(city); 
}

public StringProperty pincodeProperty(){
    return pincode;
}

public String getPincode() {
    return pincodeProperty().get();
}

public void setPincode(String pincode) {
    pincodeProperty().set(pincode); 
}

@Override
public int hashCode(){
    final int prime = 31;
    int result = 1;

    result = prime * result
    + ((city == null) ? 0 : city.hashCode())
            + ((pincode == null) ? 0 : pincode.hashCode())
            + ((destId == null) ? 0 : destId.hashCode());   
    return result;
}

@Override
public boolean equals(Object obj){
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Destination other = (Destination) obj;
    if (city == null) {
        if (other.city != null)
            return false;
    } else if (!city.equals(other.city))
        return false;
            if(pincode != other.pincode)
                return false;
    if (destId != other.destId)
        return false;
    return true;

}   
}

And here is the main class..

public class App 
{
public static void main( String[] args )
{
    EntityManagerFactory emf =       Persistence.createEntityManagerFactory("jpaDB");
    EntityManager em = emf.createEntityManager();
    EntityTransaction txn = em.getTransaction();

    Destination pk = new Destination(1,"State","8412"); 
    Inwards in = new Inwards(1,LocalDate.now(),"Abusamra");
    txn.begin(); 
    em.persist(in); 
    Inwards dest = em.find(Inwards.class, pk);
    txn.commit();
    System.out.println(dest);
    System.out.println("Order name = " + dest.getOrderName() + " "
+ "Order No. = " + dest.getOrderNo() + " " + "Order Date = "
+ dest.getOrderDate() +"Save"+dest.isSave());
}
}

But i am getting org.eclipse.persistence.exceptions.ConversionException...

here is the stacktrace...

[EL Config]: metadata: 2015-10-05 12:07:14.685--ServerSession(24424997)--Thread(Thread[main,5,main])--The access type for the persistent class [class com.qaf.jpaTut.entity.Inwards] is set to [PROPERTY].
[EL Config]: metadata: 2015-10-05 12:07:14.756--ServerSession(24424997)--Thread(Thread[main,5,main])--The access type for the persistent class [class com.qaf.jpaTut.entity.Destination] is set to [PROPERTY].
[EL Config]: metadata: 2015-10-05 12:07:14.773--ServerSession(24424997)--Thread(Thread[main,5,main])--The alias name for the entity class [class com.qaf.jpaTut.entity.Inwards] is being defaulted to: Inwards.
[EL Config]: metadata: 2015-10-05 12:07:14.777--ServerSession(24424997)--Thread(Thread[main,5,main])--The table name for entity [class com.qaf.jpaTut.entity.Inwards] is being defaulted to: INWARDS.
[EL Config]: metadata: 2015-10-05 12:07:14.814--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [getOrderNo] is being defaulted to: ORDERNO.
[EL Config]: metadata: 2015-10-05 12:07:14.816--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [isSave] is being defaulted to: SAVE.
[EL Config]: metadata: 2015-10-05 12:07:14.817--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [getPincode] is being defaulted to: PINCODE.
[EL Config]: metadata: 2015-10-05 12:07:14.817--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [getDestId] is being defaulted to: DESTID.
[EL Config]: metadata: 2015-10-05 12:07:14.817--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [getCity] is being defaulted to: CITY.
[EL Config]: metadata: 2015-10-05 12:07:14.825--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [getOrderDate] is being defaulted to: ORDERDATE.
[EL Config]: metadata: 2015-10-05 12:07:14.83--ServerSession(24424997)--Thread(Thread[main,5,main])--The column name for element [getOrderName] is being defaulted to: ORDERNAME.
[EL Info]: 2015-10-05 12:07:14.876--ServerSession(24424997)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd
[EL Fine]: connection: 2015-10-05 12:07:24.468--Thread(Thread[main,5,main])--Detected database platform: org.eclipse.persistence.platform.database.JavaDBPlatform
[EL Config]: connection: 2015-10-05 12:07:24.499--ServerSession(24424997)--Connection(1007487)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
platform=>JavaDBPlatform
user name=> ""
datasource URL=> "jdbc:derby:./jpaDB;create=true"))
[EL Config]: connection: 2015-10-05 12:07:24.505--ServerSession(24424997)--Connection(17672517)--Thread(Thread[main,5,main])--Connected: jdbc:derby:./jpaDB
User: APP
Database: Apache Derby  Version: 10.9.1.0 - (1344872)
Driver: Apache Derby Embedded JDBC Driver  Version: 10.9.1.0 - (1344872)
[EL Info]: connection: 2015-10-05 12:07:24.617--ServerSession(24424997)--Thread(Thread[main,5,main])--file:/C:/dev/JPA/jpaTut10_EmbeddedId/target/classes/_jpaDB login successful
[EL Fine]: sql: 2015-10-05 12:07:25.084--ServerSession(24424997)--Connection(17672517)--Thread(Thread[main,5,main])--CREATE TABLE INWARDS (ORDERDATE BLOB(2147483647), ORDERNAME VARCHAR(255), ORDERNO INTEGER, SAVE SMALLINT DEFAULT 0, PINCODE VARCHAR(255) NOT NULL, DESTID INTEGER NOT NULL, CITY VARCHAR(255) NOT NULL, PRIMARY KEY (PINCODE, DESTID, CITY))
Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [IntegerProperty [value: 1]], of class [class javafx.beans.property.SimpleIntegerProperty], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[destId-->INWARDS.DESTID]] with descriptor [RelationalDescriptor(com.qaf.jpaTut.entity.Destination --> [DatabaseTable(INWARDS)])], could not be converted to [class java.lang.Integer].
at org.eclipse.persistence.exceptions.ConversionException.couldNotBeConverted(ConversionException.java:75)
at org.eclipse.persistence.internal.helper.ConversionManager.convertObjectToInteger(ConversionManager.java:545)
at org.eclipse.persistence.internal.helper.ConversionManager.convertObject(ConversionManager.java:116)
at org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform.convertObject(DatasourcePlatform.java:179)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:787)
at org.eclipse.persistence.internal.jpa.CMP3Policy.createPrimaryKeyFromId(CMP3Policy.java:251)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.findInternal(EntityManagerImpl.java:797)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:719)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:588)
at com.qaf.jpaTut.App.main(App.java:63)

回答1:

Use property access instead of the default field access. This means the JPA provider will retrieve values from the get methods, instead of accessing them directly from the fields. Note also that since an IntegerProperty cannot wrap a null value, you should use int as the property type, not Integer:

@Embeddable
@Access(AccessType.PROPERTY)
public class Destination implements Serializable {

    StringProperty city;
    StringProperty pincode;
    IntegerProperty destId;

    public Destination(){
        this.city = new SimpleStringProperty();
        this.pincode = new SimpleStringProperty();
        this.destId = new SimpleIntegerProperty();
    }

    public Destination(Integer destId,String city,String pincode){
        this();
        this.destId.set(destId);
        this.city.set(city);
        this.pincode.set(pincode);  
    }

    public IntegerProperty destIdProperty(){
        return destId;
    }

    public final int getDestId(){
        return destIdProperty().get();
    }

    public final void setDestId(int destId){
        destIdProperty().set(destId);
    }

    public StringProperty cityProperty(){
        return city;
    }

    public String getCity() {
        return cityProperty().get();
    }

    public void setCity(String city) {
        cityProperty().set(city); 
    }

    public StringProperty pincodeProperty(){
        return pincode;
    }

    public String getPincode() {
        return pincodeProperty().get();
    }

    public void setPincode(String pincode) {
        pincodeProperty().set(pincode); 
    }

    @Override
    public int hashCode(){
        final int prime = 31;
        int result = 1;

        result = prime * result
        + ((city == null) ? 0 : city.hashCode())
                + ((pincode == null) ? 0 : pincode.hashCode())
                + ((destId == null) ? 0 : destId.hashCode());   
        return result;
    }

    @Override
    public boolean equals(Object obj){
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Destination other = (Destination) obj;
        if (city == null) {
            if (other.city != null)
                return false;
        } else if (!city.equals(other.city))
            return false;
                if(pincode != other.pincode)
                    return false;
        if (destId != other.destId)
            return false;
        return true;

    }   

}

There is a good discussion of this on Steven van Impe's blog.