我尝试基于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
答案 0 :(得分:0)
尝试为字段ID添加getter和setter!
答案 1 :(得分:0)
通过设置另一个LoadTimeWeaver修复异常 - InstrumentationLoadTimeWeaver并且异常消失