JPA-为persist方法生成的查询未插入所有列

时间:2019-01-11 21:12:57

标签: java jpa java-ee-6 websphere-8 openjpa

我对JPA还是很陌生,并且对于一个特定实体,实体管理器persist方法存在问题。我有一个如下表:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli($host, $user, $password) or die("Failed");

$conn->select_db($name);

$res = $conn->query("SELECT id FROM db ORDER BY id LIMIT 1");

// Declare your intention to capture the result into $id
$res->bind_result($id);
// Fetch the data which applies the binding
$res->fetch();

实体类看起来与此类似:

CREATE TABLE Items
(
  Id                INTEGER                     NOT NULL,
  GroupId           INTEGER                     NOT NULL,
  ItemId            INTEGER                     NOT NULL,
  Expires           NUMBER(9,2)
)

在存储库类中,我有以下内容:

@Entity
@Table(name = "Items")
public class Item {
    @Id
    @Column(name = "Id")
    @GeneratedValue(generator = "item_seq", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(name = "item_seq", sequenceName = "ITEM_SEQ", allocationSize = 1)
    private int id;

    @Column(name = "GroupId")
    private int groupId;

    @Column(name = "ItemId")
    private int itemId;

    @Column(name = "Expires")
    private int expires;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getGroupId() {
        return groupId;
    }
    public void setGroupId(int groupId) {
        this.groupId = groupId;
    }
    public int getItemId() {
        return itemId;
    }
    public void setItemId(int itemId) {
        this.itemId = itemId;
    }
    public int getExpires() {
        return expires;
    }
    public void setExpires(int expires) {
        this.expires = expires;
    }
}

尝试提交时,出现以下异常:

  

ORA-01400:无法将NULL插入(“ schema-name”。“ Items”。“ GroupId”)

问题在于JPA正在生成以下插入语句:

@Inject
private UserTransaction userTransaction;
...
userTransaction.begin()
Item item = new Item();
item.setItemId(itemId);
item.setGroupId(groupId);
em.persist(item);
userTransaction.commit()

我不知道为什么JPA跳过GroupId列。我已经确认groupId具有有效值,并且我还尝试将 insertable = true 添加到Column属性。正如我所提到的,这是我看到此问题的唯一实体。我到处搜寻,但没有发现类似的问题。我正在使用Java EE 6,WebSphere和OpenJPA 2.2.3。

1 个答案:

答案 0 :(得分:0)

此问题很可能是因为名称声明和实际表名混合使用大小写。对我而言,Oracle(如果我没记错的话,大约是11.2)始终创建所有表名和列名大写。您的创建脚本实际上可能等于:

CREATE TABLE ITEMS (
    ID        INTEGER    NOT NULL,
    GROUPID   INTEGER    NOT NULL,
    ITEMID    INTEGER    NOT NULL,
    EXPIRES   NUMBER(9,2)
)

在创建表时,可以通过用"包装名称来强制使用自己的大小写,例如:

CREATE TABLE "Items" ... -- and all the rest columns

实际上,您可以同时拥有例如表ItemsITEMS(实际上,Postgres也遇到了同样的问题,默认所有名称都使用小写)

无论如何:首先检查您的字段实际在数据库中的情况。

如果您的表确实具有像GroupId这样的列名,那么您可以尝试使用"在注释中“转义”该名字,例如:

@Column(name = "\"GroupId\"")

如果它们是默认的大写字母,请尝试以下操作:

@Column(name = "GROUPID")

注意:应该将其应用于所有大小写不同的字段。

特别的细节是-至少对我来说,您和Oracle似乎也是如此-无论名称如何,JPA似乎都能找到该表,但随后发现列将失败。

大多数情况下,最佳实践是在没有任何明显的偏差原因的情况下保持默认状态。因此,无论何时与Oracle合作,我们都会在各处使用大写字母。