mysql - 插入后从spring检索数据不起作用

标签 mysql spring jpa spring-data spring-data-jpa

当我使用 Spring Data Jpa 模块将数据插入 MySQL 数据库时遇到问题。

问题如下: 当我启动 Spring 应用程序时,我创建数据库并使用 SpringdataJPA 初始化数据,然后我看到数据插入到表中。之后我想插入一些与插入数据相关的数据,但之前插入的 3 条记录中只找到了 1 条。当我重新启动服务器并且我不重新创建数据并使用相同的方法搜索它时,会找到每一条记录。我搜索了两周的解决方案,但没有找到任何东西。我希望你能帮助我。

新闻

我觉得只用文字很难理解,所以我在后面插入了代码。 jpa.xml 包含所有 spring jpa 配置。 2 个实体和 init 方法。希望你能发现我的错误。

jpa.xml:

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    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/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:property-placeholder location="classpath:properties/database/database.properties" />
<!-- Declare a datasource that has pooling capabilities--> 
<!-- BoneCP configuration -->   
<bean id="SoopDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close" >
   <property name="driverClass" value="${database.driver}" />
   <property name="jdbcUrl" value="${database.url}" />
   <property name="username" value="${database.user}"/>
   <property name="password" value="${database.password}"/>
   <property name="idleConnectionTestPeriod" value="60"/>
   <property name="idleMaxAge" value="240"/>
   <property name="maxConnectionsPerPartition" value="30"/>
   <property name="minConnectionsPerPartition" value="5"/>
   <property name="partitionCount" value="2"/>
   <property name="acquireIncrement" value="5"/>
   <!-- <property name="statementsCacheSize" value="100"/> -->
   <!-- <property name="releaseHelperThreads" value="2"/> -->
</bean>

<!-- Declare a JPA entityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >

    <property name="persistenceUnitName" value="SoopDbProvider" />
    <property name="dataSource" ref="SoopDataSource"/>
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>    

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>              
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
        </props>
    </property>

    <property name="packagesToScan">
    <list>
        <value>com.soopproject.main.db</value>
    </list>
    </property>
</bean>

<!-- Db initialization bean -->
<bean id="databaseinit" class="com.soopproject.main.db.init.DatabaseInitialization" init-method="init"/>

<!-- Declare a transaction manager-->
<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

实体:

BaseEntityWithPrimary

@MappedSuperclass
@Data
@EqualsAndHashCode(callSuper = false)
public class SoopBaseEntityWithPrimary implements
        Serializable {

    @Id
    @GeneratedValue
    private long id;

}

语言:

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
public class Language extends BaseEntityWithPrimary {

    @Column(nullable = false, unique = true)
    private String shortname;

    @Column(nullable = false)
    private String longname;

    @ManyToMany(cascade = CascadeType.ALL)
    private List<TranslationsShort> languageTranslationsShorts;

}

初始化方法

@Autowired
    private UserRepository userrep;

    @Autowired
    private LanguageRepository langrep;

    @Autowired
    private ErrorCodesRepository errorrep;


private void initLanguage() {
    User systemuser = null;
    try {
        systemuser = userrep.findUserByUsername("system");
    } catch (Exception ex) {
        DatabaseException exception = new DatabaseReadException(ex);
        exception.writeLog();
    }

    List<Language> languages = new LinkedList<>();

    Language deutsch = new Language();
    deutsch.setCreateUser(systemuser);
    deutsch.setShortname("DE");
    deutsch.setLongname("Deutsch");

    Language english = new Language();
    english.setCreateUser(systemuser);
    english.setShortname("EN");
    english.setLongname("English");

    Language italiano = new Language();
    italiano.setCreateUser(systemuser);
    italiano.setShortname("IT");
    italiano.setLongname("Italiano");

    languages.add(deutsch);
    languages.add(italiano);
    languages.add(english);

    for (Language lang : languages) {
        Language l_help = null;
        try {
            l_help = langrep.findLanguageByShortname(lang.getShortname());
        } catch (Exception ex) {
            DatabaseException exception = new DatabaseReadException(ex);
            exception.writeLog();
        }
        if (l_help == null)
            try {
                langrep.saveAndFlush(lang);
            } catch (Exception e) {
                DatabaseException exception = new DatabaseWriteException(e);
                exception.writeLog();
            }
    }
}



private void initErrorCodes() {
    User systemuser = null;
    Language de = null;
    Language it = null;
    Language en = null;

    try {
        systemuser = userrep.findUserByUsername("system");
    } catch (Exception ex) {
        DatabaseException exception = new DatabaseReadException(ex);
        exception.writeLog();
    }

    try {
        de = langrep.findLanguageByShortname("DE");
    } catch (Exception ex) {
        DatabaseException exception = new DatabaseReadException(ex);
        exception.writeLog();
    }

    try {
        it = langrep.findLanguageByShortname("IT");
    } catch (Exception ex) {
        DatabaseException exception = new DatabaseReadException(ex);
        exception.writeLog();
    }

    try {
        en = langrep.findLanguageByShortname("EN");
    } catch (Exception ex) {
        DatabaseException exception = new DatabaseReadException(ex);
        exception.writeLog();
    }

问题是启动 springapplication 并设置 <prop key="hibernate.hbm2ddl.auto">create</prop> 后在 initErrorCodes 方法中,只有 it = langrep.findLanguageByShortname("IT"); 的行在数据库中查找数据。其他 2 个调用返回 null(de = langrep.findLanguageByShortname("DE"); 和 en = langrep.findLanguageByShortname("EN");)。然后我停止应用程序并查看数据库,所有数据都插入到表语言中。当我用 <prop key="hibernate.hbm2ddl.auto">none</prop> 重新启动服务器时然后所有 3 个方法调用都返回数据???!?!?!我不明白。所以可以肯定不是方法调用的问题。但我找不到错误。

最佳答案

找到 3 个中的 1 个是什么意思?您是在查询数据还是访问关系?

听起来好像正在发生某种缓存。某些 JPA 提供程序默认启用缓存,检查缓存设置,并确保正确维护双向关系。

https://en.wikibooks.org/wiki/Java_Persistence/Caching

https://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side

关于mysql - 插入后从spring检索数据不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18602295/

相关文章:

java - Spring-Data Repository @Query by class with generic class

java - 页面之间重定向 - Spring MVC

java - Spring Data JPA - 如何缓存实体,该实体包含在许多其他实体中

java - Spring JPA 投影包括链接

php - 如何从 MySql 获取给定开始和结束日期的结果?

java - Spring Batch - 从 Aws S3 读取文件

java - Embeddable 中的 JPA ElementCollection 未持久化

mysql - 创建一个表,但在复合键中包含其他实体?

php - 如何存储拖放表单生成器的数组数据

mysql - 是否为 "insert on duplicate key update"查询中的每一行执行 BEFORE INSERT 触发器