Frühling, Ruhezustand & amp; JPA: Der Aufruf von persistence für den Entitymanager scheint sich nicht auf die Datenbank festzulegen
Ich versuche zu setup Spring mit Hibernate und JPA, aber beim Versuch zu bestehen, ein Objekt, nichts scheint zu werden Hinzugefügt, um die Datenbank.
Bin mit dem folgenden:
<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" />
Und AccountManager, ich bin dabei:
@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;
}
}
Wo ac kommt von:
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;
Gibt es jemand, der zeigen kann, was ich falsch mache? Der persist Aufruf gibt, ohne das auslösen von Ausnahmen. Wenn ich danach tun em.contains(ac)
diese den Wert true zurück.
Im Falle jemand benötigt, hier ist, wie Konto definiert ist:
@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;
}
}
InformationsquelleAutor der Frage Ruben Vermeersch | 2008-12-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dank an eric und Juan Manuel ' s Antworten, ich war in der Lage, herauszufinden, dass die Transaktion nicht verpflichtet.
Hinzufügen @Transactional zu den storeAccount Methode hat den trick!
InformationsquelleAutor der Antwort Ruben Vermeersch
Ich kam tatsächlich auf eine Art und Weise, dass dies geschehen kann.
In einem injizierten EntityManager, keine updates werden immer auftreten, wenn Sie haben persistence.xml angegeben wie diese:
<persistence-unit name="primary" transaction-type="RESOURCE_LOCAL">
Müssen Sie entfernen Sie die transaction-type-Attribut, und verwenden Sie einfach die Standardeinstellung, die JTA.
InformationsquelleAutor der Antwort Nicholas DiPiazza
Nicht explizit aufrufen müssen, bestehen-Methode. Der merge-Vorgang schreiben würde, die änderungen an der DB auf commit.
InformationsquelleAutor der Antwort
Wohl, Sie halten die Transaktion aktiv, und es ist kein Aufruf von "commit", bis die anderen Methoden ausgeführt, die Förderung der aktiven Transaktions-Ende (alle "voting" für "commit" - und keine für rollback.)
Wenn du sicher bist, dass die Person, die Sie gehen, um bestehen bleiben ist ok, Sie könnten wahrscheinlich tun Sie dies:
und verwalten Sie Ihre Einheit Persistenz hinzufügen:
InformationsquelleAutor der Antwort Juan Manuel