[Spring 2.5/MySql 5] Not supported by BasicDataSource

0

Witam

Posiadam zainstalowana baze MySql 5 oraz korzystam ze Spring 2.5.6.
Kiedy chce wykonac:

        ApplicationContext ap = new ClassPathXmlApplicationContext("/resources/JdbcTemplateConf.xml");
        JpaExample jpaExample = (JpaExample)ap.getBean("jpaExample");
        JpaTemplate temp = jpaExample.getJpaTemplate();
        temp.find("SELECT * FROM osoba"); // tutaj jest blad

Kod bledu:

INFO: Building JPA container EntityManagerFactory for persistence unit 'SpringJDBCPU'
[EL Info]: 2010-10-26 00:06:22.811--ServerSession(1249086728)--EclipseLink, version: Eclipse Persistence Services - 2.0.2.v20100323-r6872
[EL Severe]: 2010-10-26 00:06:22.818--ServerSession(1249086728)--java.lang.UnsupportedOperationException: Not supported by BasicDataSource
Exception in thread "main" javax.persistence.PersistenceException: java.lang.UnsupportedOperationException: Not supported by BasicDataSource
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:397)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession
...

Plik konfiguracyjny Springa:

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test" />
        <property name="username" value="root" />
        <property name="password" value="qwert123" />
    </bean>

    <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>
    </bean>

    <bean id="jpaExample" class="springjdbc.JpaExample" >
        <property name="entityManagerFactory" ref="myEmf" />
    </bean>

Jaka implementacje DataSource mam uzyc, zeby to chodzilo? Probowalem te ze springa i Mysql ale nic nie dziala :/

0

W zaleznosci od wersji Java, powinienes uzyc DBCP 1.4 (Java 6.0) lub DBCP 1.3 (Java 5.0). Jar'y najlepiej sciagnij z Apache Commons. Poza tym, popraw query string w metodzie find(), ktora wywolujesz. Jesli wszystko inne (JPATemplate i persitence.xml) masz dobrze skonfigurowane, reszta powinna dzialac.

0

Uzywam wlasnie DBCP 1.4 bo pracuje pod JDK 6.
Zmienilem find na JpaCallback z em.persist() i nadal ten sam problem z BasicDataSource.

Moze to bedzie pomocne, ze chce, zeby dzialalo to pod JPA 2(Eclipse).

0

Uzylem org.springframework.jdbc.datasource.DriverManagerDataSource. Zadzialalo.
Zapytanie zmienilem na "SELECT c FROM Osoba c". Wykonuje sie prawidlowo.

Problem mam teraz z czym innym. Mianowicie ponizszy kod nic nie robi:

        ApplicationContext ap = new ClassPathXmlApplicationContext("/resources/JdbcTemplateConf.xml");
        JpaExample jpaExample = (JpaExample)ap.getBean("jpaExample");
        JpaTemplate temp = jpaExample.getJpaTemplate();
        List list = temp.find("SELECT c FROM Osoba c"); // TERAZ DZIALA liczba rekordow 42

        Osoba osoba = new Osoba();
        osoba.setAge((short)20);
        osoba.setName("nowy osoba test template");
        temp.persist(osoba); // I NIC - sprawdzam baze i nie ma nowego rekordu.

Najlepsze jest to, ze nawet nie wyrzuca zadnego wyjatku ani bledu.

W ten sposob tez nic sie nie dzieje:


        temp.execute(new JpaCallback(){

            @Override
            public Object doInJpa(EntityManager em) throws PersistenceException {
                Osoba o = new Osoba();
                o.setAge((short)10);
                o.setName("nowyyy");
                em.persist(o);

                return null;
            }});

Plik JdbcTemplateConf.xml wyglada teraz tak: (wkleilem calosc pomimo ze sa uzywane tylko 3 beany, reszta pochodzi z innych moich testow, ale moze cos z czym koliduje)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test" />
        <property name="username" value="root" />
        <property name="password" value="qwert123" />
    </bean>

    <bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test" />
        <property name="username" value="root" />
        <property name="password" value="qwert123" />
    </bean>

    <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource2"/>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
                <property name="generateDdl" value="true" />
<!--                <property name="databasePlatform" value="org.springframework.orm.jpa.vendor.OpenJpaDialect" />-->
            </bean>
        </property>
    </bean>

    <bean id="jpaExample" class="springjdbc.JpaExample" >
        <property name="entityManagerFactory" ref="myEmf" />
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="jdbcTemplateExample" class="springjdbc.JdbcTemplateExample">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <bean id="abstractJdbcDao" abstract="true" class="org.springframework.jdbc.core.support.JdbcDaoSupport">
        <property name="dataSource" ref="dataSource2" />
    </bean>

    <bean id="osobaDao" parent="abstractJdbcDao" class="springjdbc.JdbcOsobaDao" />
</beans>

Klasa Osoba:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package springjdbc;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.TableGenerator;

/**
 *
 * @author ryan
 */
@Entity
@Table(name = "osoba", catalog = "test", schema = "")
@NamedQueries({
    @NamedQuery(name = "Osoba.findAll", query = "SELECT o FROM Osoba o"),
    @NamedQuery(name = "Osoba.findById", query = "SELECT o FROM Osoba o WHERE o.id = :id"),
    @NamedQuery(name = "Osoba.findByName", query = "SELECT o FROM Osoba o WHERE o.name = :name"),
    @NamedQuery(name = "Osoba.findByAge", query = "SELECT o FROM Osoba o WHERE o.age = :age")})
public class Osoba implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
//    @TableGenerator (name="OSOBA_TABLE_GENERATOR", table="SEQUENCE_GENERATOR_TABLE", pkColumnName="SEQUENCE_NAME", valueColumnName="SEQUENCE_VALUE", pkColumnValue="OSOBA_SEQUENCE", allocationSize=1)
//    @GeneratedValue(strategy=GenerationType.TABLE, generator="OSOBA_TABLE_GENERATOR")
    @Basic(optional = false)
    @Column(name = "id")
    private Short id;
    @Basic(optional = false)
    @Column(name = "name")
    private String name;
    @Basic(optional = false)
    @Column(name = "age")
    private short age;

    public Osoba() {
    }

    public Osoba(Short id) {
        this.id = id;
    }

    public Osoba(Short id, String name, short age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Short getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public short getAge() {
        return age;
    }

    public void setAge(short age) {
        this.age = age;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Osoba)) {
            return false;
        }
        Osoba other = (Osoba) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "springjdbc.Osoba[id=" + id + "]";
    }

}

Dodatkowo, nie wiem czemu nie moge skorzystac z NamedQuery, ktore sa przeciez w adnotacji w klasie Osoba. Kiedy sie na nie powoluje za pomoca Query q = em.createNamedQuery("findByName"); to dostaje wyjatek "query argument name not found"

0

Miszczu a nie zapomniales gdzies rozpoczac transakcji i jej zrobic commita?

0

W sumie moze rozwine - gdy czytasz z bazy, do JPA pozwala zrobic to poza transakcja. Wtedy wszystkie zwrocone encje sa w stanie detached (dlatego Tobie dziala to zapytanie). Jesli zrobisz to w transakcji, beda attached dopoki ich nie usuniesz albo nie zamkniesz PersistenceContext.
Aby zapisac / updatowac encje, musi ona byc w stanie managed / persisted. To robi metoda persist(). Aby zpaisac do bazy, musisz wywolac flush() albo zrobic commita transakcji. Przy czym flush() sprawdzi czy jest jakas aktywna transakcja i w tTwoim przypadku obstawiam ze sie wywali wyjatkiem typu "No active EntityTransaction" czy podobnie.

A propos JpaTemplate ze Springa - w dokumentacji tej klasy jest zalecane aby uzywac JPA bezposrednio, a JpaTemplate jest tylko po to aby API bylo kompletne (jest JmsTemplate, jest JdbcTemplate, jest HibernateTemplate, to jest i JpaTemplate). Przemysl, moze zechcesz postapic jak zalecaja sami tworcy Springa?

0

Jak wyzej. A co do wyjatku przy named query, to dla zapytan z parametrami powinienes podac te parametry(Query.setParameter(String, Object)) lub, jesli robisz selecta przez JpaTemplate, mozesz uzyc JpaTemplate.findByNamedQueryAndNamedParams(String, Map<String, ?>)

0
ws napisał(a)

JpaTemplate.findByNamedQueryAndNamedParams(String, Map<String, ?>)

Juz kiedys zauwazylem za z nazwami w SpringSource nie jest najlepiej.

0

Zrobilem tak: zaimplementowalem klase JpaDaoOsoba ktora rozszerza JpaDaoSupport i implementuje interfejs OsobaIF. Metody klasy JpaDaoOsoba sa adnotowane @Transactional. Np:

@Transactional
public class JpaDaoOsoba extends JpaDaoSupport implements OsobaIF{

    @Override
    public void persistOsoba(Osoba o){
        getJpaTemplate().persist(o);
    }
}

::. Czyli jesli dobrze rozumiem, mam operowac bezposrednio na EntityManager tak? Czyli obiekty DAO nie musza rozszerzac klasy JpaDaoSupport bo po co mi w takim razie metoda getJpaTemplate()? Czyli po prostu korzystac z @PersistentContext?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.