2008-12-17 74 views
17

我试图设置Spring使用Hibernate和JPA,但是当试图保留一个对象时,似乎没有任何东西添加到数据库中。Spring,Hibernate和JPA:在entitymanager上调用persist似乎没有提交到数据库

现在用的是以下几点:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="url" value="${jdbc.url}"/> 
    <property name="driverClassName" value="${jdbc.driverClassName}"/> 
    <property name="username" value="${jdbc.username}"/> 
    <property name="password" value="${jdbc.password}"/> 
</bean> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="persistenceUnitName" value="BankingWeb" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="generateDdl" value="true" /> 
      <property name="showSql" value="true" /> 
      <property name="databasePlatform" value="${hibernate.dialect}" /> 
     </bean> 
    </property> 
</bean> 

<tx:annotation-driven/> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 

<bean name="accountManager" class="ssel.banking.dao.jpa.AccountManager" /> 
<bean name="userManager" class="ssel.banking.dao.jpa.UserManager" /> 

而在的AccountManager,我做:

@Repository 
public class AccountManager implements IAccountManager { 

    @PersistenceContext private EntityManager em; 

    /* -- 8< -- Query methods omitted -- 8< -- */ 

    public Account storeAccount(Account ac) { 
    ac = em.merge(ac); 
     em.persist(ac); 
     return ac; 
    } 
} 

其中Ac来自:

Account ac = new Account(); 
    ac.setId(mostRecent.getId()+1); 
    ac.setUser(user); 
    ac.setName(accName); 
    ac.setDate(new Date()); 
    ac.setValue(0); 
    ac = accountManager.storeAccount(ac); 
    return ac; 

是否有任何人谁可以点我做错了什么?持续调用返回时不会抛出异常。如果事后我做em.contains(ac),这将返回true。

如果有人需要,这里的客户是如何定义的:

@SuppressWarnings("serial") 
@Entity 
@NamedQueries({ 
     @NamedQuery(name = "Account.AllAccounts", query = "SELECT a FROM Account a"), 
     @NamedQuery(name = "Account.Accounts4User", query = "SELECT a FROM Account a WHERE user=:user"), 
     @NamedQuery(name = "Account.Account4Name", query = "SELECT a FROM Account a WHERE name=:name"), 
     @NamedQuery(name = "Account.MaxId", query = "SELECT MAX(a.id) FROM Account a"), 
     @NamedQuery(name = "Account.Account4Id", query = "SELECT a FROM Account a WHERE id=:id"), 
    }) 
public class Account extends AbstractNamedDomain { 
    @Temporal(TemporalType.DATE) 
    @Column(name = "xdate") 
    private Date date; 

    private double value; 

    @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE}) 
    @JoinColumn(name="userid") 
    private User user; 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER) 
    @OrderBy("date") 
    private List<AccountActivity> accountActivity = new ArrayList<AccountActivity>(); 

    public List<AccountActivity> getAccountActivity() { 
     return accountActivity; 
    } 

    public void setAccountActivity(List<AccountActivity> accountActivity) { 
     this.accountActivity = accountActivity; 
    } 

    public Date getDate() { 
     return date; 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 

    public double getValue() { 
     return value; 
    } 

    public void setValue(double value) { 
     this.value = value; 
    } 

    public void addAccountActivity(AccountActivity activity) { 
     // Make sure ordering is maintained, JPA only does this on loading 
     int i = 0; 
     while (i < getAccountActivity().size()) { 
      if (getAccountActivity().get(i).getDate().compareTo(activity.getDate()) <= 0) 
       break; 
      i++; 
     } 
     getAccountActivity().add(i, activity); 
    } 
} 

@MappedSuperclass public abstract class AbstractNamedDomain extends AbstractDomain { 

    private String name; 

    public AbstractNamedDomain() { 

    } 

    public AbstractNamedDomain(String name) { 

     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

@MappedSuperclass public abstract class AbstractDomain implements Serializable { 

    @Id @GeneratedValue 
    private long id = NEW_ID; 

    public static long NEW_ID = -1; 

    public long getId() { 
     return id; 
    } 

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

    public boolean isNew() { 

     return id==NEW_ID; 
    } 
} 
+0

嘿ruben,我正在做类似的事情,但我有一个persistence.xml文件,你有一个,为什么或为什么不?谢谢 – bmw0128 2009-07-15 16:36:44

回答

18

感谢eric和胡安曼努埃尔的回答,我能够找出交易没有承诺。

将@Transactional添加到storeAccount方法的窍门!

+0

这就是你解决这个问题所做的一切吗? – 2009-04-24 15:51:41

+0

在我的情况下,我不得不将@Transactional添加到我的课程的入口点。在我做了持久化的方法之前,我只有@Transactional。不知道我是否完全理解那里发生了什么。 – 2009-04-24 18:32:12

1

也许你保持交易活跃,他并没有叫“承诺”,直到运行配套活动事务结束的其他方法(全“投票”的承诺,并没有回滚)

如果你确定你要坚持的实体是确定你也许可以做到这一点。

@TransactionManagement(TransactionManagementType.BEAN) 
public class AccountManager implements IAccountManager { ..} 

并管理你的实体持久性加入:

@Resource 
private SessionContext sessionContext; 

public Account storeAccount(Account ac) { 
    sessionContext.getUserTransaction().begin(); 
    ac = em.merge(ac); 
    em.persist(ac); 
    sessionContext.getUserTransaction().commit(); 
    return ac; 
} 
+0

@TransactionManagement是EJB。 – 2009-04-24 15:20:25

1

你不明确需要调用persist方法。合并操作会在提交时将更改写入数据库。

4

我实际上遇到了另一种可能发生这种情况的方式。

<persistence-unit name="primary" transaction-type="RESOURCE_LOCAL">

您需要删除事务型属性,只使用默认是JTA:

在注入的EntityManager,如果你的persistence.xml这样的规定将永远不会出现更新。

相关问题