使用注释映射默认列值
@Entity
@Table(name = "J_CNTRY")
public class CountryEntity {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "myTableGenerator")
@TableGenerator(name = "myTableGenerator", allocationSize = 5, pkColumnName = "pkName", valueColumnName = "pkValue", table = "j_cntry_pk_table")
private Long id;
private String country;
@Generated(GenerationTime.INSERT)
@Column(name = "CREATION_TIME", columnDefinition = "DATE default '15-JUL-1980'", insertable = false)
private Date creationTime;
public CountryEntity() {
}
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(final String country) {
this.country = country;
}
public Date getCreationTime() {
return creationTime;
}
@Override
public String toString() {
return "Country [id=" + id + ", country=" + country + ", creationTime="
+ creationTime + "]";
}
}
如果我不设置其值,我期望为每行插入值“15-JUL-1980”。
但它没有按预期工作。我在这里做错了什么吗?
由于某些原因,我想在应用程序中设置默认值,而不是在数据库中设置。
更新:
最初我只尝试不使用“insertable = false”。
作为一个新手,我尝试了不同的选择并保留了该选项。
这是我正在运行的测试用例:
@Test
public void testCreateCountry4() {
final CountryEntity a1 = new CountryEntity();
a1.setCountry("Xxxx");
final Session currentSession = sessionFactory.getCurrentSession();
final Long savedId = (Long) currentSession.save(a1);
System.out.println("Saved with ID = " + savedId);
currentSession.flush();
System.out.println("Saved object = " + a1);
assertNotNull(savedId);
}
及其产生的输出:
Saved with ID = 85
Hibernate:
/* insert entities.CountryEntity
*/ insert
into
J_CNTRY
(country, id)
values
(?, ?)
Hibernate:
/* get generated state entities.CountryEntity */ select
countryent_.CREATION_TIME as CREATION3_2_
from
J_CNTRY countryent_
where
countryent_.id=?
Saved object = Country [id=85, country=Xxxx, creationTime=null]
表:
CREATE TABLE "FOO"."J_CNTRY"
( "ID" VARCHAR2(255 BYTE) NOT NULL,
"COUNTRY" VARCHAR2(255 BYTE),
"CREATION_TIME" DATE,
CONSTRAINT "J_CNTRY_PK" PRIMARY KEY ("ID")
}
@Entity
@Table(name = "J_CNTRY")
public class CountryEntity {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "myTableGenerator")
@TableGenerator(name = "myTableGenerator", allocationSize = 5, pkColumnName = "pkName", valueColumnName = "pkValue", table = "j_cntry_pk_table")
private Long id;
private String country;
@Generated(GenerationTime.INSERT)
@Column(name = "CREATION_TIME", columnDefinition = "DATE default '15-JUL-1980'", insertable = false)
private Date creationTime;
public CountryEntity() {
}
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(final String country) {
this.country = country;
}
public Date getCreationTime() {
return creationTime;
}
@Override
public String toString() {
return "Country [id=" + id + ", country=" + country + ", creationTime="
+ creationTime + "]";
}
}
I'm expecting the value '15-JUL-1980' to be inserted for each row IF I DONOT set its value.
But its not working as expected. Am I doing anything wrong here?
For some reasons, I want to set the default value at the application and Not at the database.
UPDATE:
Initially i tried without 'insertable = false' only.
As a newbie, I was trying different options and had kept that option.
Here is the test case which I'm running:
@Test
public void testCreateCountry4() {
final CountryEntity a1 = new CountryEntity();
a1.setCountry("Xxxx");
final Session currentSession = sessionFactory.getCurrentSession();
final Long savedId = (Long) currentSession.save(a1);
System.out.println("Saved with ID = " + savedId);
currentSession.flush();
System.out.println("Saved object = " + a1);
assertNotNull(savedId);
}
and the output it has produced:
Saved with ID = 85
Hibernate:
/* insert entities.CountryEntity
*/ insert
into
J_CNTRY
(country, id)
values
(?, ?)
Hibernate:
/* get generated state entities.CountryEntity */ select
countryent_.CREATION_TIME as CREATION3_2_
from
J_CNTRY countryent_
where
countryent_.id=?
Saved object = Country [id=85, country=Xxxx, creationTime=null]
Table:
CREATE TABLE "FOO"."J_CNTRY"
( "ID" VARCHAR2(255 BYTE) NOT NULL,
"COUNTRY" VARCHAR2(255 BYTE),
"CREATION_TIME" DATE,
CONSTRAINT "J_CNTRY_PK" PRIMARY KEY ("ID")
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上,即使您因为
insertable = false
设置了一个值,creationTime
也永远不会成为 SQL INSERT 语句的一部分。什么不能完全工作?你能显示该表的 DDL 脚本吗?到底执行了什么 DML INSERT 语句? Oracle 是否正确设置了默认值?插入后不把它放回实体中吗?什么时候会失败?
以防万一,您是否缺少
creationTime
上的Temporal
注释?根据 JPA 1.0 规范:我会添加一个
@Temporal(TemporalType.DATE)
。虽然不确定这是否能解决问题,但回答上述问题可能有助于诊断问题。
Column
注释的columnDefinition
元素用于指定为列生成 DDL 时使用的 SQL 片段,仅此而已。如果您不使用 JPA 提供程序生成 DDL,并且您的表没有定义任何DEFAULT
,则不会发生任何情况。因此,在您的情况下,我可能会使用生命周期回调并在
PrePersist
期间设置日期 ifnull
:参考
Actually, the
creationTime
will never be part of the SQL INSERT statement even if you set a value because of theinsertable = false
.What is not working exactly? Can you show the DDL script for the table? What DML INSERT statement is performed exactly? Does Oracle set the default appropriately? Don't you get it back in the entity after the insert? When does it fail?
Just in case, aren't you missing a
Temporal
annotation on thecreationTime
? According to the JPA 1.0 spec:I would add a
@Temporal(TemporalType.DATE)
.Not sure this will solve the issue though but answering the above questions might help to diagnose the issue.
The
columnDefinition
element of theColumn
annotation is used to specify the SQL fragment that is used when generating the DDL for the column, that's all. If you don't use the JPA provider to generate the DDL and if your table doesn't have anyDEFAULT
defined, nothing will happen.So in your case, I would probably use a lifecyle callback and set the date if
null
duringPrePersist
:Reference