Körperschaften, die Nicht Beibehalten - Spring + Hibernate + JPA
Ich bin mit Spring + Hibernate + Java Persistence API (JPA und ich haben eine situation, wo ich nicht an meine entities persistent in der Datenbank. Ich habe eine service-Klasse, annotiert mit @Transactional. Es verwendet eine DAO enthält ein EntityManager injiziert. Wenn ich rufen Sie die Funktion auf das service-Objekt, ich sehe ein Bündel auswählt, für den liest sich das DAO zu tun, aber keine updates/deletes, die als ein Ergebnis mischt und entfernt, ausgestellt durch mein DAO. Sicherlich gibt es etwas falsch mit meinem setup, aber ich kann es nicht sehen.
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="pu">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.InformixDialect" />
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
<property name="hibernate.showsql" value="true" />
<property name="hibernate.cache.use_second_level_cache"
value="false" />
</properties>
</persistence-unit>
config.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/testdb" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="pu" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
</bean>
</property>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<context:annotation-config/>
</beans>
AccountService.java
@Service("accountService")
@Transactional(propagation=Propagation.REQUIRED)
public class AccountService {
private static final Logger log = Logger.getLogger(AccountService.class);
@Autowired
private UserDAO userDAO;
public void activateUser(String username, String activationCode) {
PendingActivation pendingActivation = userDAO.getPendingActivation(
username, activationCode);
Client client = pendingActivation.getClient();
if (!userDAO.removePendingActivation(pendingActivation)) {
log.warn("Unable to remove pending activation");
}
if (!userDAO.enableUser(client)) {
log.error("Unable to enable client");
return;
}
return;
}
}
UserDAOImpl.java
@Repository("userDAO")
public class UserDAOImpl implements UserDAO, Serializable {
private static final long serialVersionUID = 1L;
private static Logger log = Logger.getLogger(UserDAOImpl.class);
@PersistenceContext
EntityManager em;
@Override
public PendingActivation getPendingActivation(String username, String activationCode) {
Query q = em.createNamedQuery("getActivationCode")
.setParameter("activationCode", activationCode);
PendingActivation pendingActivation = null;
try {
pendingActivation = (PendingActivation)q.getSingleResult();
return pendingActivation;
}
catch (Exception e) {
log.warn("Could not retrieve activation code " + activationCode + " for user " + username, e);
return null;
}
}
@Override
public boolean enableUser(Client client) {
try {
client.setEnabled(true);
client = em.merge(client); //this never generates an update
}
catch(Exception e) {
log.error("Unable to enable client: " + client.getUsername(), e);
return false;
}
return true;
}
@Override
public boolean removePendingActivation(PendingActivation pendingActivation) {
try {
pendingActivation = (PendingActivation)em.getReference(PendingActivation.class, pendingActivation.getPendingActivationId());
em.remove(pendingActivation); //this never generates a delete
}
catch(Exception e) {
log.warn("Unable to remove activation: " + pendingActivation.getActivationCode(), e);
return false;
}
return true;
}
}
AccountActivationController.java
@Controller
public class AccountActivationController {
@Autowired
@Qualifier("accountService")
AccountService accountService;
@RequestMapping("activate.do")
public String doActivate(
@RequestParam("activationCode") String activationCode,
@RequestParam("username") String username,
ModelMap model) {
UnitCriteria unitCriteria = accountService.activateUser(username, activationCode);
if (unitCriteria == null) {
return "account/activationError";
}
model.addAttribute("fromActivation", true);
return "forward:search.do?" + unitCriteria.toUrlParams(true);
}
}
- Wo ruft Ihr activateUser aus?
- Ich rufe es aus einem servlet. Ich habe den code Hinzugefügt, um den ursprünglichen post. Danke!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ok, ich habe herausgefunden, das problem. Es dauerte ewig, um es herauszufinden, und hatte nichts zu tun mit meiner Datenbank config, also ich will den Menschen helfen, die ähnliche Probleme.
Frühjahr-Dokumentation besagt Folgendes:
Was nicht geschrieben in meinem ursprünglichen post ist mein-servlet-definition, die den folgenden Zeilen Konfigurations-code:
myServlet.xml
Dieser bringt alle kommentierten Bohnen, einschließlich Controller, Services und Repositories, in die servlet-Kontext anstelle der Anwendung Kontext. Und darin liegt das problem. Wenn der Frühling sieht für Bohnen annotiert mit @Transactional (aufgrund der Existenz von
<tx:annotation-driven/>
in meinem config.xml Datei) ist auf der Suche nach Ihnen in den Anwendungskontext. Und, basiert auf meine config gepostet wurde, in meinem vorherigen thread, es gibt keine Bohnen geladen in meinem Anwendungskontext... Sie sind alle in der servlet-Kontext. Also, wenn mein servlet ruft die Bohnen annotiert mit @Service & @Transactional es war mit Bohnen, die waren nicht verpackt von transaction proxies. Es werden somit keine Transaktionen. Der trick (eher, die richtige Art und Weise) war die änderung meiner config-Dateien in der folgenden Weise:myServlet.xml
config.xml
Diese Konfiguration stellt sicher, dass alle Steuerungen bestehen in der servlet-Kontext-und Transaktions-Services und Repositories existieren in den Anwendungskontext die ist, wo Sie hingehören. Und endlich, nach vielen schlaflosen Nächte, meine Datenbank schreibt beharren.
Können wir Ihnen die Controller in servlet-context.xml wie folgt
Dies wird sicherstellen, dass nur Controller existiert nur in der servlet-Kontext.
In root-context.xml verwenden Sie die folgenden
Damit werden die anderen Komponenten als Controller besteht im Anwendungskontext. Ich suchte für diese Lösung eine Menge, da ohne dieses PPV war nicht die Aktualisierung der Datenbank, hoffe das hilft jemandem