简体   繁体   English

实体不通过Spring(CrudRepository)在TomEE上持久化

[英]Entity not persisting via Spring(CrudRepository) on TomEE

I have issues trying to persist an Entity to a PostgreSQL Database using Springs CrudRepository interface. 我尝试使用Springs CrudRepository接口将实体持久化到PostgreSQL数据库时遇到问题。 I have had quite some issues setting this up with the correct values both on TomEE and adjusting the configuration of Spring itself. 我在TomEE上调整正确的值并调整Spring本身的配置时遇到了一些问题。 I tried briefly to use hibernate, but issues just got worse, so I switched back to OpenJpa that is bundled with TomEE. 我曾尝试使用hibernate,但问题变得更糟,所以我切换回与TomEE捆绑在一起的OpenJpa。

I have a bit of experience with plain JavaEE and am creating this application to learn Spring and a friend of mine needs a Spring application to fool around with deployment on a TomEE based ApplicationServer, thus those two are requirements. 我有一些普通JavaEE的经验,我正在创建这个应用程序来学习Spring,我的一个朋友需要一个Spring应用程序来在基于TomEE的ApplicationServer上进行部署,因此这两个是需求。 I might go a bit overboard with the amount of code I attach, but I rather let you see what is there so you get a good overview. 我可能会对我附加的代码量有点过分,但我宁愿让你看看有什么,所以你得到了一个很好的概述。

Components I have developed and a brief description of what I'm doing, expecting and actually seeing. 我开发的组件以及我正在做什么,期待和实际看到的简要描述。 Components: 组件:

  • CoworkerController (RESTful Spring Controller) CoworkerController(RESTful Spring Controller)
  • CoworkerService (Spring Service to interact with Controller and Repository) CoworkerService(Spring Service与Controller和Repository交互)
  • CoworkerRepository (extends Spring CrudRepository) CoworkerRepository(扩展Spring CrudRepository)
  • Coworker (Entity that is supposed to be persisted) 同事(应该坚持的实体)

Flow of my actions: 我的行动流程:

  • Send a POST via curl with firstname lastname to the RESTful service 通过curl发送带有firstname lastname的POST到RESTful服务
  • Getting a Status 200 with the ID of the persisted Entity 获取具有持久实体ID的状态200
  • Checking PostgreSQL and RESTful service if I can query for my created Coworker 如果我可以查询我创建的Coworker,请检查PostgreSQL和RESTful服务

What I'm expecting: 我期待的是:

  • Controller accepts POST and calls Service to persist the Coworker 控制器接受POST并调用服务来保持同事
  • Service tells Repository to save the Coworker 服务告诉Repository保存Coworker
  • Repository persists Coworker Entity via Spring magic 存储库通过Spring魔术持续存储Coworker实体
  • Spring/OpenJPA magic that connects to DataSource, create ID and return Entity on success 连接到DataSource的Spring / OpenJPA魔术,创建ID并在成功时返回Entity
  • See SQL queries during that happening 在此期间查看SQL查询
  • Repository receives persisted Entity and returns to Service 存储库接收持久化实体并返回服务
  • Service returns Entity to Controller 服务将实体返回给Controller
  • Controller returns Entity.id to the caller of the REST service Controller将Entity.id返回给REST服务的调用者

What I see and what I don't see but would expect to see: 我看到的和我看不到的但希望看到的:

  • Controller works as expected 控制器按预期工作
  • Service logs correct user info 服务日志更正用户信息
  • @PrePersist creates a Date Object (Logger) @PrePersist创建一个Date对象(Logger)
  • SQL statement logs about openjpa sequence queries 有关openjpa序列查询的SQL语句日志
  • MISSING: No SQL INSERT statement about persisting my Entity MISSING:没有关于持久化我的实体的SQL INSERT语句
  • Repository returns new Coworker to Service 存储库将新的Coworker返回给服务
  • Service logs the supposed to be persisted Entity with creationDate and id(eg 1) 服务使用creationDate和id记录应该是持久化的实体(例如1)
  • Controller returns id to caller of REST (eg 1) Controller将id返回给REST的调用者(例如1)
  • Neither REST nor SQL Queries show any Coworker in the Database :( REST和SQL查询都没有显示数据库中的任何同事:(

My configuration files have gotten quite a mess after trying all different kinds of troubleshooting found via google, SO and lots of tutorials. 在通过google,SO和许多教程尝试所有不同类型的故障排除后,我的配置文件变得非常混乱。 After spending now several days trying to figure out what the issue is, I come now here and hope you might be able to point me to my error. 现在花了几天时间试图找出问题所在,我现在来到这里,希望你能指出我的错误。

Coworker.java Coworker.java

@Entity
public class Coworker implements Serializable {

    @Transient
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long coworkerId;
    private String firstName;
    private String lastName;
    @Temporal(TemporalType.DATE)
    private Date creationDate;
    @Temporal(TemporalType.DATE)
    private Date lastUpdatedDate;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "coworker", fetch = FetchType.EAGER)
    private Set<Timeframe> timeframes = new HashSet<Timeframe>();

    @PrePersist
    private void setDateBeforePersisting() {
        logger.info("Inside prepersisting a Coworker");
        creationDate = new Date();
        // Set the last updated Date to the creation date
        lastUpdatedDate = (Date) creationDate.clone();
    }
    // ...snip.. Getters, Setters, equals, hashcode created by IDEA here
}

CoworkerController.java CoworkerController.java

@Controller
@RequestMapping(value = "coworker")
public class CoworkerController {
    @Autowired
    CoworkerService service;
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public Long create(@RequestBody Coworker coworker) {
        logger.info("Post to create Coworker.");
        if (coworker == null) {
            logger.info("Coworker == null");
        } else {
            logger.info("Coworker.firstName: " + coworker.getFirstName() + " Coworker.lastName: " + coworker.getLastName());
        }
        final Coworker coworker1 = service.addNewCoworker(coworker);
        logger.info("Persisted coworker, id: " + coworker1.getCoworkerId());
        return coworker1.getCoworkerId();
    }
}

CoworkerServiceImpl.java CoworkerServiceImpl.java

@Service
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public class CoworkerServiceImpl implements CoworkerService  {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public Coworker addNewCoworker(Coworker coworker) {
        logger.info("Service saving coworker: " + coworker.getFirstName() + " " + coworker.getLastName());
        final Coworker save = repo.save(coworker);
        logger.info("Service saved coworker, is it != null? " + (save != null));
        logger.info("First name: " + save.getFirstName() + " Last name: " + save.getLastName() + " Date created: " + save.getCreationDate() + " id: " + save.getCoworkerId());
        return save;
    }

}

CoworkerRepository.java CoworkerRepository.java

public interface CoworkerRepository extends CrudRepository<Coworker, Long> {
    // Several queries here, but nothing that should interfer with
    // CrudRepository.save(S)
}

persistence.xml persistence.xml中

<?xml version="1.0" encoding="UTF-8" ?>
<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_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="timeregistration" transaction-type="RESOURCE_LOCAL">
        <non-jta-data-source>java:/comp/env/jdbc/timeregistration</non-jta-data-source>
        <class>org.xezz.timeregistration.model.Coworker</class>
        <class>org.xezz.timeregistration.model.Customer</class>
        <class>org.xezz.timeregistration.model.Project</class>
        <class>org.xezz.timeregistration.model.Timeframe</class>
    </persistence-unit>
</persistence>

timeregistration-servlet.xml timeregistration-servlet.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <mvc:resources mapping="/static/**" location="/static/"/>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven />
    <jpa:repositories base-package="org.xezz.timeregistration.repositories"/>
    <context:component-scan base-package="org.xezz.timeregistration" />
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="persistenceUnitName" value="timeregistration"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
                <property name="generateDdl" value="true"/>
                <property name="database" value="POSTGRESQL"/>
                <property name="showSql" value="true"/>
            </bean>
        </property>
    </bean>
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:/comp/env/jdbc/timeregistration"/>
        <property name="resourceRef" value="true" />
    </bean>
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="mediaTypes">
            <map>
                <entry key="html" value="text/html"/>
                <entry key="json" value="application/json"/>
            </map>
        </property>
        <property name="viewResolvers">
            <list>
                <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
                    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
                    <property name="prefix" value="/WEB-INF/jsp/"/>
                    <property name="suffix" value=".jsp"/>
                </bean>
            </list>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                    <property name="prefixJson" value="true"/>
                </bean>
            </list>
        </property>
    </bean>
</beans>

Consolelog Consolelog

Mai 09, 2013 11:16:03 PM org.xezz.timeregistration.controller.CoworkerController create
Information: Post to create Coworker.
Mai 09, 2013 11:16:03 PM org.xezz.timeregistration.controller.CoworkerController create
Information: Coworker.firstName: Bastian Coworker.lastName: Koch
Mai 09, 2013 11:16:03 PM org.xezz.timeregistration.services.impl.CoworkerServiceImpl addNewCoworker
Information: Service saving coworker: Bastian Koch
Mai 09, 2013 11:16:03 PM org.xezz.timeregistration.model.Coworker setDateBeforePersisting
Information: Inside prepersisting a Coworker
Mai 09, 2013 11:16:03 PM org.xezz.timeregistration.services.impl.CoworkerServiceImpl addNewCoworker
Information: Service saved coworker, is it != null? true
59370  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 850080749> executing prepstmnt 553961214 SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE WHERE ID = ? FOR UPDATE [params=?]
59421  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 850080749> [50 ms] spent
59423  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 683618612> executing prepstmnt 540500434 INSERT INTO OPENJPA_SEQUENCE_TABLE (ID, SEQUENCE_VALUE) VALUES (?, ?) [params=?, ?]
59474  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 683618612> [50 ms] spent
59476  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 334967428> executing prepstmnt 512431903 SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE WHERE ID = ? FOR UPDATE [params=?]
59479  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 334967428> [3 ms] spent
59480  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 334967428> executing prepstmnt 1033569251 UPDATE OPENJPA_SEQUENCE_TABLE SET SEQUENCE_VALUE = ? WHERE ID = ? AND SEQUENCE_VALUE = ? [params=?, ?, ?]
59493  timeregistration  TRACE  [http-bio-8080-exec-1] openjpa.jdbc.SQL - <t 1732295982, conn 334967428> [12 ms] spent
Mai 09, 2013 11:16:04 PM org.xezz.timeregistration.services.impl.CoworkerServiceImpl addNewCoworker
Information: First name: Bastian Last name: Koch Date created: Thu May 09 23:16:03 CEST 2013 id: 1
Mai 09, 2013 11:16:04 PM org.xezz.timeregistration.controller.CoworkerController create
Information: Persisted coworker, id: 1

tomee.xml tomee.xml

<?xml version="1.0" encoding="UTF-8"?>
<tomee>
    <Resource id="jdbc/timeregistration" type="DataSource">
        JdbcDriver org.postgresql.Driver
        JdbcUrl jdbc:postgresql://localhost/timeregdb
        UserName timereg
        Password supersecretpassword
        jtaManaged false
        InitialSize 0
        MaxWait 50
        MaxActive 20
        MaxIdle 20
    </Resource>
</tomee>

pom.xml 的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.xezz</groupId>
    <artifactId>timeregistration</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>4.11</junit.version>
        <javax-persistence.version>2.0.0</javax-persistence.version>
        <javax-inject.version>1</javax-inject.version>
        <spring.version>3.2.2.RELEASE</spring.version>
        <spring-data.version>1.3.1.RELEASE</spring-data.version>
        <jackson.version>2.1.4</jackson.version>
        <jackson-mapper-asl.version>1.9.12</jackson-mapper-asl.version>
        <jaxb-api.version>2.2.7</jaxb-api.version>
        <slf4j-api.version>1.7.1</slf4j-api.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j-api.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>javax.persistence</artifactId>
            <version>${javax-persistence.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>${javax-inject.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>${jackson-mapper-asl.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>${jaxb-api.version}</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Thanks for any help in advance, I have wasted so much time right now trying to track down different errors (especially following hibernate stuff, which was more time consuming than I dare to tell), so right now I just have to ask someone else to look over this and share wisdom with me and don't hesitate if you need more information (I can update github with the current codebase if needed). 感谢您提前提供任何帮助,我现在浪费了太多时间试图追踪不同的错误(特别是关注hibernate的东西,这比我敢说的更耗时),所以现在我只需要问别人看看这个并与我分享智慧,如果您需要更多信息,请不要犹豫(如果需要,我可以使用当前代码库更新github)。

I think you are using the wrong transactionManager in your spring configuration xml. 我认为你在spring配置xml中使用了错误的transactionManager。 Since you want to use spring with jpa, you should use the JpaTransactionManager . 由于您希望将spring与jpa一起使用,因此您应该使用JpaTransactionManager

For your example, I think your configuration should look as follows: 对于您的示例,我认为您的配置应如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在春季通过登录的用户保留实体 - Persisting an entity via a logged in user in spring Spring Boot中的Hibernate JPA / CrudRepository实体锁定 - Hibernate JPA/CrudRepository Entity Locking in Spring Boot 通过RestController从Spring CrudRepository流式传输 - Streaming from Spring CrudRepository via RestController Spring:默认情况下,如何使用 CrudRepository 返回具有实体连接引用的所有对象 - Spring: How to return all objects with joined references of an entity by default with CrudRepository 如何在 Spring 数据 JDBC 的 CrudRepository 的查询中引用实体? - How to reference entity in Query in CrudRepository in Spring Data JDBC? 在Spring Boot实体上设置功能不持久 - set function on Spring Boot entity not persisting Spring Data Jpa没有将实体持久化到MySQL - Spring Data Jpa not persisting the entity to mysql Spring Boot实体没有持久化或数据库表 - Spring boot entity without persisting or db table 在 Spring MVC、CrudRepository、Thymeleaf 中搜索(通过文本字段和按钮) - Search (via text field and button) in Spring MVC, CrudRepository, Thymeleaf 使用 CrudRepository.save(Entity) 使用 spring-data-jdbc 插入具有预定义 @ID 字段的实体 - Using CrudRepository.save(Entity) to insert an Entity with predefined @ID field using spring-data-jdbc
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM