Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring, Hibernate & JPA: Calling persist on entitymanager does not seem to commit to database

I'm trying to setup Spring using Hibernate and JPA, but when trying to persist an object, nothing seems to be added to the database.

Am using the following:

<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" />

And in AccountManager, I'm doing:

@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;
    }
}

Where ac comes from:

    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;

Is there anyone who can point out what I'm doing wrong? The persist call returns without throwing exceptions. If afterwards I do em.contains(ac), this returns true.

In case anyone needed, here's how Account is defined:

@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;
    }
}
like image 518
Ruben Vermeersch Avatar asked Dec 17 '08 15:12

Ruben Vermeersch


People also ask

What is Hibernate and spring?

Spring is used to develop application from desktop to Web. Hibernate is used to access data layer and Struts is used for Web frameworks. Get to know everything about Java coding with special approach, industry expert offers training to the candidates with real-time projects. Spring.

Does spring use Hibernate?

Spring Data JPA is really a set of dependencies that makes it easier to work with a JPA provider. Hibernate is one of several JPA providers. This means you can use Spring Data JPA without using Hibernate (if you really wanted to).

Does spring boot have Hibernate?

spring-boot-starter-data-jpa (required) : It includes spring data, hibernate, HikariCP, JPA API, JPA Implementation (default is hibernate), JDBC and other required libraries.

What is spring Hibernate and JPA?

What Is the Difference Between Hibernate and Spring Data JPA? Hibernate is a JPA implementation, while Spring Data JPA is a JPA Data Access Abstraction. Spring Data offers a solution to GenericDao custom implementations. It can also generate JPA queries on your behalf through method name conventions.


1 Answers

Thanks to eric and Juan Manuel's answers, I was able to figure out that the transaction wasn't committed.

Adding @Transactional to the storeAccount method did the trick!

like image 181
Ruben Vermeersch Avatar answered Oct 01 '22 15:10

Ruben Vermeersch