PSQLException:错误:表“*”上的插入或更新违反了外键约束

时间:2013-09-03 13:29:52

标签: java postgresql jpa jdbc glassfish

我尝试将所有数据从一个数据库插入另一个数据库。这两个数据库具有相同的结构(它们使用相同的实体)。我使用PostgreSQL 9.1,Glassfish 4.0,EclipseLink(JPA 2.1)和Java EE 7 Web。

这些是实体:

@Entity
public class Store extends BaseEntity {

    @NotNull
    private String name;

   /*
    * required
    */
    @OneToMany(cascade = CascadeType.PERSIST)
    private List<Price> listPrices;

   /*
    * required
    */
    @OneToMany(cascade = CascadeType.PERSIST)
    private List<BusinessHours> listBusinessHours;

    @OneToOne(cascade = CascadeType.PERSIST, optional = false)
    private PointCoordinates pointCoordinates;
    ...
}

例如@OneToMany注释实体之一:

@Entity
public class BusinessHours extends BaseEntity {

    private Boolean holiday;

    ...
}

BaseEntity包含带有GenerationType.SEQUENCE的Id和serialVersionUID。

的persistence.xml:

<persistence-unit name="restDBFromRawData" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/RestDBFromRawData</jta-data-source>

    <class>info.mycompany.entities.BusinessHours</class>
    <class>info.mycompany.entities.Store</class>
    <class>info.mycompany.entities.PointCoordinates</class>
    <class>info.mycompany.entities.Price</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
    </properties>
  </persistence-unit>

<persistence-unit name="restClientDB" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/RestClientDB</jta-data-source>

    <class>info.mycompany.entities.BusinessHours</class>
    <class>info.mycompany.entities.Store</class>
    <class>info.mycompany.entities.PointCoordinates</class>
    <class>info.mycompany.entities.Price</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
      <property name="eclipselink.ddl-generation.output-mode" value="both"/>
    </properties>
   </persistence-unit>

如果我尝试从一个数据库获取所有数据并尝试将它们插入另一个数据库(addStoresToRestClientDB):

@Stateless
public class StoreOutputService {

    @EJB
    StoreOutputDAO storeOutputDAO;

    @EJB
    StoreOutputRestClientDAO storeOutputRCDAO;

    public List<Store> getAllStores() {
        return storeOutputDAO.findAll();
    }

    public void addStoresToRestDBFromRawData() {
        //this works fine
        ...
        for (Store store : listStore) {
            storeOutputDAO.edit(store);
        }
    }

    public void addStoresToRestClientDB() {

        List<Store> listStore = getAllStores();
        //size of list is right, the same like I insert in "addStoresToRestDBFromRawData"

        for (Store store : listStore) {
            storeOutputRCDAO.edit(store);
        }
    }
}

我收到以下错误:

WARNING:   Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: insert or update on table "store_businesshours" violates foreign key constraint "fk_store_businesshours_listbusinesshours_id"
  Detail: Key (listbusinesshours_id)=(55) is not present in table "businesshours".
Error Code: 0
Call: INSERT INTO STORE_BUSINESSHOURS (listBusinessHours_ID, Store_ID) VALUES (?, ?)
    bind => [2 parameters bound]
Query: DataModifyQuery(name="listBusinessHours" sql="INSERT INTO STORE_BUSINESSHOURS (listBusinessHours_ID, Store_ID) VALUES (?, ?)")
...
Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "store_businesshours" violates foreign key constraint "fk_store_businesshours_listbusinesshours_id"
  Detail: Key (listbusinesshours_id)=(55) is not present in table "businesshours".
...
WARNING:   StandardWrapperValve[info.mycompany.web.ApplicationConfig]: Servlet.service() for servlet info.mycompany.web.ApplicationConfig threw exception
org.postgresql.util.PSQLException: ERROR: insert or update on table "store_businesshours" violates foreign key constraint "fk_store_businesshours_listbusinesshours_id"
  Detail: Key (listbusinesshours_id)=(55) is not present in table "businesshours".

DAO应该没问题。 StoreOutputDAO使用持久性单元restDBFromRawDataStoreOutputRestClientDAO使用持久性单元restClientDB

JDBC jdbc/RestDBFromRawData使用带有javax.sql.ConnectionPoolDataSource ressourcetype的连接池(classname:org.postgresql.ds.PGConnectionPoolDataSource),另一个JDBC“jdbc / RestClientDB”使用“javax.sql.XADataSource” ressourcetype(classname:org.postgresql.xa.PGXADataSource)。如果我在“jdbc / RestClientDB”中使用相同的配置,如“jdbc / RestDBFromRawData”,我收到以下错误消息:“本地事务已经有1个非XA资源”。

$GLASSFISH_HOME/glassfish/lib$GLASSFISH_HOME/domains/domain1/lib包含PostgreSQL驱动程序“postgresql-9.1-901.jdbc4.jar。

如果我在数据库中查看pgAdmin,一切看起来都很好。它们具有相同的结构,其他一切正常:将数据插入另一个数据库并插入StoreOutputDAOStoreOutputRestClientDAO之外的数据。

更新 BaseEntity:

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private int id;

    public int getId() {
        return id;
    }

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

1 个答案:

答案 0 :(得分:2)

发生此错误是因为其他数据库中不存在营业时间。确保插入它。

你是否坚持使用它,它的Id是如何定义的?在将其迁移到其他数据库时,您可能需要将其Id和版本归零。