堆中的类实例

时间:2014-05-17 20:22:36

标签: java jpa eclipselink classloader

我尝试基于spring框架和Eclipselink JPA创建一个简单的JPA应用程序。

首先初始化一个EntityManagerBean:

public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

    entityManagerFactoryBean.setJpaDialect(new EclipseLinkJpaDialect());

    EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
    vendorAdapter.setShowSql(true);
    vendorAdapter.setGenerateDdl(true);
    vendorAdapter.setDatabasePlatform("org.eclipse.persistence.platform.database.PostgreSQLPlatform");

    entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPackagesToScan("org.egzi.diplom.model");
    entityManagerFactoryBean.setLoadTimeWeaver(new SimpleLoadTimeWeaver());

    //to update existing table (alter table)+
    Properties additionalProperties = new Properties();
    additionalProperties.setProperty("eclipselink.ddl-generation", "create-or-extend-tables");
    additionalProperties.setProperty("eclipselink.ddl-generation.output-mode","database");

    entityManagerFactoryBean.setJpaProperties(additionalProperties);

    return entityManagerFactoryBean;
}

在DAO课程中尝试坚持某个实体:

@PersistenceContext
EntityManager entityManager;

@Transactional(propagation = Propagation.REQUIRED)
public void createTODO() {
    Todo todo = new Todo();
    todo.setSummary("a");
    todo.setDescription("b");


    entityManager.persist(todo);
}

实体类:

@Entity
public class Todo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String summary;
    private String description;

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Todo [summary=" + summary + ", description=" + description
                + "]";
    }

}

但是当我运行这样的代码时,我有一个例外:

java.lang.IllegalArgumentException: Object: Todo [summary=a, description=b] is not a known entity type.
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4228)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:496)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:262)
    at com.sun.proxy.$Proxy22.persist(Unknown Source)
    at org.egzi.diplom.spring.GeneratorImpl.createTODO(GeneratorImpl.java:59)

当我查看eclipselink源代码时,我发现HashMap以Class作为关键字:

org.eclipse.persistence.internal.sessions.AbstactSession.getDescriptor(类):

descriptor = this.descriptors.get(theClass);

当我开始调试我的代码时,我发现描述符map已经有了Todo.class的键。我发现HashMap和Todo.class中的classHash是不同的。我从Inteliji IDEA开始我的代码。

我的例子中有什么问题?

更新 发现描述符HashMap中的类在org.springframework.instrument.classloading.SimpleInstrumentableClassLoader@14bb2297上有一个链接 但我的Todo对象有另一个: sun.misc.Launcher$AppClassLoader@58644d46

2 个答案:

答案 0 :(得分:0)

尝试为字段ID添加getter和setter!

答案 1 :(得分:0)

通过设置另一个LoadTimeWeaver修复异常 - InstrumentationLoadTimeWeaver并且异常消失