2

我正在使用spring和hibernate做一个项目。Hibernate 显示“insert sql”语句,但表是空的。我在stackoverflow中检查了类似的问题。但我找不到任何与我的问题类似的问题。

// 这些是我的实体类

//歌曲类

    @Entity
    @Table(name="Song", catalog="myFavMusic")
    public class Song implements Serializable {

        @Id
        @GeneratedValue(strategy = IDENTITY)
        private Integer id;

        public Song(){

        }
        public Song(String title, Album album, Singer singer, Integer rating) {
            super();
            Title = title;
            this.album = album;
             this.singer = singer;
             this.rating = rating;
        }

        private String Title;

        @ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
        @JoinColumn(name = "ALBUM_ID", nullable = false)
        private Album album;

        @ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
        @JoinColumn(name = "SINGER_ID", nullable = false)
        private Singer singer;

        private Integer rating;
    }

// 专辑

    @Entity
    public class Album {    
        public Album(String title, String type, Integer releasedYear) {
            super();
            this.title = title;
            this.type = type;
            this.releasedYear = releasedYear;
        }

        @Id
        @GeneratedValue
        @Column(name = "ALBUM_ID", unique = true, nullable = false, length = 20)
        private Integer id;

        @Column(name = "TITLE", unique = true, nullable = false)
        private String title;

        @Column(name = "TYPE", unique = true, nullable = false)
        private String type;

        @Column(name = "RELEASED_YEAR", unique = true, nullable = false)
        private Integer releasedYear;
    }

//歌手类

    @Entity
    public class Singer {

        public Singer(String singerName, Date dob) {
           super();
           this.singerName = singerName;
           this.dob = dob;
        }

        @Id
        @GeneratedValue
        @Column(name = "SINGER_ID", unique = true, nullable = false, length = 20)
        private Integer id;
        private String singerName;
        private Date dob;
   }

// 这是我的 DAO 接口

   public interface MusicDao {
           public void addSong(Song song);
       public List<Song> listAllSongsBySpec(SongSpec spec);
   }

// 这是我的 DAO 实现

    public class MusicDaoImpl implements MusicDao {

        @Autowired
        private SessionFactory sessionFactory;

        public void addSong(Song song) {
            sessionFactory.getCurrentSession().save(song);
        }
    }

// 弹簧配置

    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource"><ref bean="dataSource" /></property>
    <property name="hibernateProperties">
           <props>
                   <prop  key="hibernate.dialect">  org.hibernate.dialect.MySQLDialect
                    </prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
    <property name="packagesToScan" value="com.myprojects.myfavmusic.domain" />
</bean>
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>
<bean class=
            "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>file:src/test/resources/config/database-unitFav.properties
        </value>
    </property>
</bean>
<bean id="musicDao" class="com.myprojects.myfavmusic.dao.impl.MusicDaoImpl"
    autowire="byName">
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

// 我的单元测试来测试这个

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"file:src/test/ApplicationContext- unitFav.xml"})
    public class MusicDaoImplTest extends TestCase {

        @Autowired
        private MusicDao musicDao;
        @Test
        @Transactional
        public void testAddSong() {
            Album album = new Album("album1","movie",2009);
            Singer singer = new Singer("singer 1",new Date());
            Song song = new Song("song 1",album,singer,0);
            musicDao.addSong(song);
            assertTrue(true);
       }

}

这对我来说似乎是一个奇怪的问题。Hibernate 不会抱怨任何错误。但是当我检查数据库时没有记录。我认为这可能是冲洗模式的问题。但我相信默认的冲洗模式是自动的。无论如何,我也尝试指定冲洗模式。但问题仍然存在。请帮我解决这个问题?

提前致谢,阿伦

4

1 回答 1

3

实际上这是我所期望的行为(测试结束后什么都没有)。

当您在测试@Transactional结束时标记测试方法时,对该方法所做的所有更改都将自动回滚。(如参考指南中所述

当您将您@Transactional的 dao 移动到测试用例而不是测试用例时,测试不再是事务性的,数据将保留。我不会将此作为最佳实践,因为对于初学者来说,应该是事务性的不是您的 dao,而是您的服务层。除此之外,您不希望来自一项测试的数据干扰另一项测试。

你真的应该在你的测试方法中测试数据的存在(而不是使用 sql 浏览器或类似的东西。)

@ContextConfiguration(locations={"file:src/test/ApplicationContext- unitFav.xml"})
public class MusicDaoImplTest extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    private MusicDao musicDao;

    @Autowired
    private SessionFactory sf;

    @Test
    public void testAddSong() {
        Album album = new Album("album1","movie",2009);
        Singer singer = new Singer("singer 1",new Date());
        Song song = new Song("song 1",album,singer,0);
        musicDao.addSong(song);
        sf.getCurrentSession().flush(); // Similate a flush at the end of a transaction
        int count = countRowsInTable("song"); // Data should be in the table
        assertEquals(1, count);
   }

类似的东西。

最后请注意,您的测试用例也有轻微缺陷,您混合了 JUnit3 和 JUnit4 类型。您正在扩展TestCaseJUnit3,而您正在使用@Test方法上的注释进行测试。这是等待发生的麻烦(奇怪的测试结果、执行等)。

于 2013-11-04T08:27:49.817 回答