java - 合并时生成错误的 SQL 更新查询

标签 java sql-server jpa openjpa websphere-7

当在带有 MS SQL Server 2008 的 WebSphere Application Server 7 上使用 EntityManager 的合并方法来更新数据库中的实体时,生成错误的 SQL 查询(SET 关键字后没有更新参数(请参阅下面的堆栈跟踪))。

当我尝试合并实体而不对数据库进行任何更改时,很可能会出现此问题,但这并不能让我更接近解决方案。

有人对此有解决方案/解决方法吗?

Caused by: <openjpa-1.2.4-SNAPSHOT-r422266:1481680 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: Неправильный синтаксис около ключевого слова "WHERE". {prepstmnt 1814850604 UPDATE COMPANY_REF SET  WHERE ID = ? [params=(int) 11751]} [code=156, state=S0001]
FailedObject: ru.hostco.jpa.Company-11751
    at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4315)
    at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4280)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:102)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:72)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:132)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:90)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:73)
    at org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flushPrimaryRow(OperationOrderUpdateManager.java:203)
    at org.apache.openjpa.jdbc.kernel.OperationOrderUpdateManager.flush(OperationOrderUpdateManager.java:89)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:91)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:74)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:721)
    at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
    ... 51 more
<小时/>

编辑 1

有一些实体实体和合并的代码。

@Stateless
public class CompanyPersistanceManagerImpl implements CompanyPersistanceManager {

    private static Logger _logger = Logger
            .getLogger(CompanyPersistanceManagerImpl.class.getName());

    @PersistenceContext(unitName = "ListGatewayJPA")
    private EntityManager entityManager;
    @EJB
    private SettingsPersistenceManager settingsPersistenceManager;

    ...

    @Override
    public Company updateCompany(Company company) {
        company = entityManager.merge(company);
        entityManager.flush();
        return company;
    }

    ...

}
<小时/>
@Entity
@Table(name = "COMPANY_REF")
@NamedQueries({
        @NamedQuery(name = "getAllCompanies", query = "SELECT c FROM Company c ORDER BY c.name"),
        @NamedQuery(name = "getCompanyByName", query = "SELECT c FROM Company c WHERE c.name = :name"),
        @NamedQuery(name = "getCompanyByDeltaCode", query = "SELECT c FROM Company c WHERE c.code = :code"),
        @NamedQuery(name = "getCompanyById", query = "SELECT c FROM Company c WHERE c.id = :ID"), })
public class Company implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private int id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "INN")
    private String inn;

    @Column(name = "ENCODING")
    private String encoding;

    @Column(name = "CODE")
    private String code;

    @Column(name = "ACC", length = 20)
    private String acc;

    @Column(name = "FEE_ACC", length = 20)
    private String feeAcc;

    @Column(name = "WWA", length = 7)
    private String wwa;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "BENATTR_ID")
    @ForeignKey
    private Benattr benattr;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "COMPANY_TRANSFERTYPE_REL", joinColumns = { @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "TRANSFER_TYPE_ID", referencedColumnName = "ID") })
    private Set<TransferType> transferType;

    public static enum WWA_VALUES {
        NEVER, ALWAYS, REQUEST
    }

    @Transient
    private RGAORG info;

    @Transient
    private boolean selected = false;

    public Company() {
        super();
    }

    public String getAcc() {
        return acc;
    }

    public void setAcc(String acc) {
        this.acc = acc;
    }

    public int getId() {
        return this.id;
    }

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

    public String getName() {
        return this.name;
    }

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

    public String getInn() {
        return this.inn;
    }

    public void setInn(String inn) {
        this.inn = inn;
    }

    public String getEncoding() {
        return this.encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public Set<TransferType> getTransferType() {
        if (transferType == null) {
            transferType = new HashSet<TransferType>();
        }
        return transferType;
    }

    public void setTransferType(Set<TransferType> transferType) {
        this.transferType = transferType;
    }

    public TransferType[] getTransferTypeAsArray() {
        TransferType[] arr = null;
        if (transferType != null) {
            arr = new TransferType[transferType.size()];
            return transferType.toArray(arr);
        } else {
            arr = new TransferType[0];
            return arr;
        }

    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public RGAORG getInfo() {
        return info;
    }

    public void setInfo(RGAORG info) {
        this.info = info;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Company)) {
            return false;
        }
        Company other = (Company) obj;
        if (id != other.id) {
            return false;
        }
        return true;
    }

    public String getFeeAcc() {
        return feeAcc;
    }

    public void setFeeAcc(String feeAcc) {
        this.feeAcc = feeAcc;
    }

    public String getWwa() {
        return wwa;
    }

    public void setWwa(String wwa) {
        this.wwa = wwa;
    }

    public Benattr getBenattr() {
        return benattr;
    }

    public void setBenattr(Benattr benattr) {
        this.benattr = benattr;
    }

}

最佳答案

我认为您使用的是不稳定的 OpenJPA 1.2.4-SNAPSHOT 版本。我将其降级到 1.2.3,看看问题是否仍然出现。

另一方面,我认为仅当 OpenJPA 没有任何要更新的字段时才会发生错误(请测试)。在这种情况下,我只需用 try-catch block 包围代码,并忽略错误(您要求解决方法)。

关于java - 合并时生成错误的 SQL 更新查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19836859/

相关文章:

java - 金融应用程序中必需的货币数据类型?

java - 从多个列表生成所有组合

java - 从 JFileChooser 获取带引号的路径?

java - 避免使用 if 子句

sql - 如何在 SQL Server (2005) 中找到 WITH RECOMPILE 元数据?

java - 为什么 Spring 在第一次调用 Repository 方法后关闭 Runnable 中的 DB-session?

java - JPA Lazy Fetch 在获取集合时不起作用

java - 在 PMD 中使用 JSP 自定义规则

sql - 将存储为 VARCHAR 的 BINARY 转换为 BINARY

sql-server - 离线存储一些 SQL Server 数据