我试图通过Spring和Java Persistence API在我的数据库中持久化一个Test类型的对象
我的数据库中有一个Test表,我创建了相应的Entity Class:
@Entity
@Table(name = "test")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Test2.findAll", query = "SELECT t FROM Test t"),
@NamedQuery(name = "Test2.findByTestId", query = "SELECT t FROM Test t WHERE t.testId = :testId"),
@NamedQuery(name = "Test2.findByTestint", query = "SELECT t FROM Test t WHERE t.testint = :testint"),
@NamedQuery(name = "Test2.findByText", query = "SELECT t FROM Test t WHERE t.text = :text")})
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "testId")
private Integer testId;
@Column(name = "testint")
private Integer testint;
@Basic(optional = false)
@Temporal(TemporalType.TIMESTAMP)
private Date endtime;
@Column(name = "text")
private String text;
public Test() {
}
public Test(Integer testId) {
this.testId = testId;
}
public Test(Integer testId, Date starttime, Date endtime) {
this.testId = testId;
this.starttime = starttime;
this.endtime = endtime;
}
public Integer getTestId() {
return testId;
}
public void setTestId(Integer testId) {
this.testId = testId;
}
public Integer getTestint() {
return testint;
}
public void setTestint(Integer testint) {
this.testint = testint;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
然后我创建了一个实现TestDao接口的Jpa类:
@Repository("testDao")
public class JpaTestDao implements TestDao {
public JpaTestDao(EntityManagerFactory emf) {
this.emf = emf;
}
@PersistenceUnit
private EntityManagerFactory emf;// = null;
EntityManager em;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
@Transactional
@Override
public void create(Test test) {
em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
em.persist(test);
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
}
TestDao界面:
public interface TestDao {
public void create(Test t);
}
最后,我收到以下错误:
Could not instantiate bean class [com.mycompany.jpa.JpaTestDao]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.mycompany.jpa.JpaTestDao.
请你帮助我吗?我无法弄清楚出了什么问题?
答案 0 :(得分:6)
因为你在JpaTestDao中添加了一个额外的构造函数,如下所示:
public JpaTestDao(EntityManagerFactory emf) {
this.emf = emf;
}
Java将不再为您生成默认构造函数。您需要添加默认构造函数:
JpaTestDao() {}
这是非常标准的Java行为。在转向Spring之前,绝对建议在Java基础知识上更加扎实。或者,也许你只是犯了一个诚实的错误。 :)
此外,正如其他人所提到的,您将需要注入EntityManager而不是注入EntityManagerFactory。然后,您需要使用以下命令注释EntityManager:
@PersistenceContext(unitName="greatUnitName")
您将在Spring Config中设置unitName。 JavaConfig示例如下:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException
{
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setJpaVendorAdapter(envConfig.jpaVendorAdapter());
factory.setPackagesToScan("java.pkg.pkg1","java.pkg.pkg2");
factory.setPersistenceUnitName("greatUnitName");
return factory;
}
@Bean
public EntityManager entityManager() throws SQLException
{
return entityManagerFactory().getObject().createEntityManager();
}
@Bean
public PlatformTransactionManager transactionManager() throws SQLException
{
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return jpaTransactionManager;
}
//... snip DataSource setup