Question

I am currently learning JPA. And in the doc, it noted that only when entity is detached to be remotely by other JVM, that it need to be Serializable.

However, for testing purpose, I created my Entity as an Inner Private Class of my persistence Class (a CDI). And when I attempt to persist the Entity using EntityManager. I get an exception as follow:

Caused by: Exception [EclipseLink-7155] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class minh.ea.common.Ultilities.DatabaseLogger] for the attribute [this$0] on the entity class [class minh.ea.common.Ultilities.DatabaseLogger$LogRecord] is not a valid type for a serialized mapping. The attribute type must implement the Serializable interface.

This exception as I understood, meaning my entity Attribute need to be Serializable as well as the Class. So what is the reason, where is it being passed to?

All of these are running under GlassFish 4.0 Container. JPA using EclipseLink 2.1

My implementation of the persistence and the inner Entity is as follow:

package minh.ea.common.Ultilities;

import java.util.Date;
import javax.enterprise.context.ApplicationScoped;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.transaction.Transactional;

/**
 *
 * @author Minh
 */

@ApplicationScoped
@minh.ea.common.Ultilities.qualifiers.Database
public class DatabaseLogger implements Logger {

    @PersistenceContext
    private EntityManager em;

    private final long MAX_SIZE=2097152;

    public DatabaseLogger(){

    }

    @Override
    @Transactional
    public void info(Object obj) {
        em.persist(new RecordEntry("INFO", new Date(), obj.toString()));
    }

    @Override
    @Transactional
    public void warn(Object obj) {
        em.persist(new RecordEntry("WARN", new Date(), obj.toString()));
    }

    @Override
    @Transactional
    public void error(Object obj) {
        em.persist(new RecordEntry("ERROR", new Date(), obj.toString()));
    }

    @Override
    @Transactional
    public void fatal(Object obj) {
        em.persist(new RecordEntry("FATAL", new Date(), obj.toString()));
    }

    @Entity
    public class LogRecord{

        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
        private String type;
        @Temporal(TemporalType.TIMESTAMP)
        private Date time;
        private String message;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public Date getTime() {
            return time;
        }

        public void setTime(Date time) {
            this.time = time;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public LogRecord() {
        }

        public LogRecord(String type, Date time, String message) {
            this.type = type;
            this.time = time;
            this.message = message;
        }
    }

}

Best regards,

Was it helpful?

Solution

As per this reference, valid Entity classes must be top-level classes, meaning that your inner class won't work.

Try pulling it out into a Entity class of its own, as it would be in a proper system, and persist again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top