JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)
一、自定义映射的表名
1.
@Entity
@Table(name = "USERS")
public class User implements Serializable {
// ...
}
2.用定界符
//@Table(name = "`USER`")的标准
@Table(name = "`USER`") //JPA的标准
@Table(name = "\"USER\"")
若全部SQL都加定界符, create an orm.xml file and add the setting <delimited-identifiers/> to its <persistence-unit-defaults> section,Hibernate then enforces quoted identifiers everywhere.
3.若要映射的表都有前缀,则可用实现PhysicalNamingStrategy接口或继承已有的实现
package org.jpwh.shared; import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; /**
* Prefixes all SQL table names with "CE_", for CaveatEmptor.
*/
public class CENamingStrategy extends
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl { @Override
public Identifier toPhysicalTableName(Identifier name,
JdbcEnvironment context) {
return new Identifier("CE_" + name.getText(), name.isQuoted());
} }
You have to enable the naming-strategy implementation in persistence.xml:
<persistence-unit>name="CaveatEmptorPU">
...
<properties>
<property name="hibernate.physical_naming_strategy" value="org.jpwh.shared.CENamingStrategy" />
</properties>
</persistence-unit>
4.用ImplicitNamingStrategy
二、自定义实体名
1.
package my.other.model;
@javax.persistence.Entity(name = "AuctionItem")
public class Item {
// ...
}
三、动态生成SQL
To disable generation of INSERT and UPDATE SQL statements on startup, you need native Hibernate annotations:
@Entity
@org.hibernate.annotations.DynamicInsert
@org.hibernate.annotations.DynamicUpdate
public class Item {
// ...
}
四、实体相关选项
1.Making an entity immutable
@Entity
@org.hibernate.annotations.Immutable
public class Bid {
// ...
}
2.Mapping an entity to a subselect
When an instance of ItemBidSummary is loaded, Hibernate executes your custom SQL
SELECT as a subselect:
Synchronize注解的作用:Hibernate will then know it has to flush modifications of Item and Bid instances
before it executes a query against ItemBidSummary
package org.jpwh.model.advanced; import javax.persistence.Entity;
import javax.persistence.Id; @Entity
@org.hibernate.annotations.Immutable
@org.hibernate.annotations.Subselect(
value = "select i.ID as ITEMID, i.ITEM_NAME as NAME, " +
"count(b.ID) as NUMBEROFBIDS " +
"from ITEM i left outer join BID b on i.ID = b.ITEM_ID " +
"group by i.ID, i.ITEM_NAME"
) // TODO Table names are case sensitive, Hibernate bug HHH-8430
@org.hibernate.annotations.Synchronize({"Item", "Bid"})
public class ItemBidSummary { @Id
protected Long itemId; protected String name; protected long numberOfBids; public ItemBidSummary() {
} // Getter methods...
public Long getItemId() {
return itemId;
} public String getName() {
return name;
} public long getNumberOfBids() {
return numberOfBids;
} // ...
}
五、测试代码
1.
package org.jpwh.test.advanced; import org.jpwh.env.JPATest;
import org.jpwh.model.advanced.Bid;
import org.jpwh.model.advanced.Item;
import org.jpwh.model.advanced.ItemBidSummary;
import org.testng.annotations.Test; import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.UserTransaction;
import java.math.BigDecimal; import static org.testng.Assert.assertEquals; public class MappedSubselect extends JPATest { @Override
public void configurePersistenceUnit() throws Exception {
configurePersistenceUnit("AdvancedPU");
} @Test
public void loadSubselectEntity() throws Exception {
long ITEM_ID = storeItemAndBids(); UserTransaction tx = TM.getUserTransaction();
try {
tx.begin();
EntityManager em = JPA.createEntityManager(); {
ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID);
// select * from (
// select i.ID as ITEMID, i.ITEM_NAME as NAME, ...
// ) where ITEMID = ? assertEquals(itemBidSummary.getName(), "AUCTION: Some item");
}
em.clear(); { // Hibernate will synchronize the right tables before querying
Item item = em.find(Item.class, ITEM_ID);
item.setName("New name"); // No flush before retrieval by identifier!
//ItemBidSummary itemBidSummary = em.find(ItemBidSummary.class, ITEM_ID); // Automatic flush before queries if synchronized tables are affected!
Query query = em.createQuery(
"select ibs from ItemBidSummary ibs where ibs.itemId = :id"
);
ItemBidSummary itemBidSummary =
(ItemBidSummary)query.setParameter("id", ITEM_ID).getSingleResult(); assertEquals(itemBidSummary.getName(), "AUCTION: New name");
} tx.commit();
em.close();
} finally {
TM.rollback();
}
} public Long storeItemAndBids() throws Exception {
UserTransaction tx = TM.getUserTransaction();
tx.begin();
EntityManager em = JPA.createEntityManager();
Item item = new Item();
item.setName("Some item");
item.setDescription("This is some description.");
em.persist(item);
for (int i = 1; i <= 3; i++) {
Bid bid = new Bid();
bid.setAmount(new BigDecimal(10 + i));
bid.setItem(item);
em.persist(bid);
}
tx.commit();
em.close();
return item.getId();
} }
Note that Hibernate doesn’t flush automatically before a find() operation—only before a Query is executed, if necessary. Hibernate detects that the modified Item will affect the result of the query, because the ITEM table is synchronized with ItemBid-Summary . Hence, a flush and the UPDATE of the ITEM row are necessary to avoid the
query returning stale data.
2.
package org.jpwh.model.advanced; import org.jpwh.model.Constants; import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.sql.Blob;
import java.util.Date; @Entity
public class Item { /*
The <code>Item</code> entity defaults to field access, the <code>@Id</code> is on a field. (We
have also moved the brittle <code>ID_GENERATOR</code> string into a constant.)
*/
@Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @org.hibernate.annotations.Type(type = "yes_no")
protected boolean verified = false; // JPA says @Temporal is required but Hibernate will default to TIMESTAMP without it
@Temporal(TemporalType.TIMESTAMP)
@Column(updatable = false)
@org.hibernate.annotations.CreationTimestamp
protected Date createdOn; // Java 8 API
// protected Instant reviewedOn; @NotNull
@Basic(fetch = FetchType.LAZY) // Defaults to EAGER
protected String description; @Basic(fetch = FetchType.LAZY)
@Column(length = 131072) // 128 kilobyte maximum for the picture
protected byte[] image; // Maps to SQL VARBINARY type @Lob
protected Blob imageBlob; @NotNull
@Enumerated(EnumType.STRING) // Defaults to ORDINAL
protected AuctionType auctionType = AuctionType.HIGHEST_BID; @org.hibernate.annotations.Formula(
"substr(DESCRIPTION, 1, 12) || '...'"
)
protected String shortDescription; @org.hibernate.annotations.Formula(
"(select avg(b.AMOUNT) from BID b where b.ITEM_ID = ID)"
)
protected BigDecimal averageBidAmount; @Column(name = "IMPERIALWEIGHT")
@org.hibernate.annotations.ColumnTransformer(
read = "IMPERIALWEIGHT / 2.20462",
write = "? * 2.20462"
)
protected double metricWeight; @Temporal(TemporalType.TIMESTAMP)
@Column(insertable = false, updatable = false)
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.ALWAYS
)
protected Date lastModified; @Column(insertable = false)
@org.hibernate.annotations.ColumnDefault("1.00")
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.INSERT
)
protected BigDecimal initialPrice; /*
The <code>@Access(AccessType.PROPERTY)</code> setting on the <code>name</code> field switches this
particular property to runtime access through getter/setter methods by the JPA provider.
*/
@Access(AccessType.PROPERTY)
@Column(name = "ITEM_NAME") // Mappings are still expected here!
protected String name; /*
Hibernate will call <code>getName()</code> and <code>setName()</code> when loading and storing items.
*/
public String getName() {
return name;
} public void setName(String name) {
this.name =
!name.startsWith("AUCTION: ") ? "AUCTION: " + name : name;
} public Long getId() { // Optional but useful
return id;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} public String getShortDescription() {
return shortDescription;
} public BigDecimal getAverageBidAmount() {
return averageBidAmount;
} public double getMetricWeight() {
return metricWeight;
} public void setMetricWeight(double metricWeight) {
this.metricWeight = metricWeight;
} public Date getLastModified() {
return lastModified;
} public BigDecimal getInitialPrice() {
return initialPrice;
} public Date getCreatedOn() {
return createdOn;
} public boolean isVerified() {
return verified;
} public void setVerified(boolean verified) {
this.verified = verified;
} public byte[] getImage() {
return image;
} public void setImage(byte[] image) {
this.image = image;
} public Blob getImageBlob() {
return imageBlob;
} public void setImageBlob(Blob imageBlob) {
this.imageBlob = imageBlob;
} public AuctionType getAuctionType() {
return auctionType;
} public void setAuctionType(AuctionType auctionType) {
this.auctionType = auctionType;
}
}
3.
package org.jpwh.model.advanced; import org.jpwh.model.Constants; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal; @Entity
@org.hibernate.annotations.Immutable
public class Bid { @Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull
protected BigDecimal amount; @ManyToOne(optional = false, fetch = FetchType.LAZY) // NOT NULL
@JoinColumn(name = "ITEM_ID") // Actually the default name
protected Item item; public Long getId() {
return id;
} public BigDecimal getAmount() {
return amount;
} public void setAmount(BigDecimal amount) {
this.amount = amount;
} public Item getItem() {
return item;
} public void setItem(Item item) {
this.item = item;
}
}
JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)的更多相关文章
- JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-002identity详解
一.简介 1.You now have three methods for distinguishing references: Objects are identical if they occ ...
- JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-001区分entities and value types
一.介绍 1.这种引用方式不对,但删除时不能级联 要这种引用方式 2.The Bid class could be a problem. In object-oriented modeling, th ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-005控制类型映射(Nationalized、@LOB、@org.hibernate.annotations.Type)
一.简介 1. 2. 3. 4. to override this default mapping. The JPA specification has a convenient shortcut a ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-001Mapping basic properties(@Basic、@Access、access="noop"、@Formula、@ColumnTransformer、@Generated、 @ColumnDefaul、@Temporal、@Enumerated)
一.简介 在JPA中,默认所有属性都会persist,属性要属于以下3种情况,Hibernate在启动时会报错 1.java基本类型或包装类 2.有注解 @Embedded 3.有实现java.io. ...
- JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-006Mixing inheritance strategies(@SecondaryTable、@PrimaryKeyJoinColumn、<join fetch="select">)
一.结构 For example, you can map a class hierarchy to a single table, but, for a particular subclass, s ...
- JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-003Table per concrete class with unions(@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)、<union-subclass>)
一.代码 1. package org.jpwh.model.inheritance.tableperclass; import org.jpwh.model.Constants; import ja ...
- JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-002Table per concrete class with implicit polymorphism(@MappedSuperclass、@AttributeOverride)
一.结构 二.代码 1. package org.jpwh.model.inheritance.mappedsuperclass; import javax.persistence.MappedSup ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-007UserTypes的用法(@org.hibernate.annotations.Type、@org.hibernate.annotations.TypeDefs、CompositeUserType、DynamicParameterizedType、、、)
一.结构 二.Hibernate支持的UserTypes接口 UserType —You can transform values by interacting with the plain JD ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-006类型转换器( @Converter(autoApply = true) 、type="converter:qualified.ConverterName" )
一.结构 二.代码 1. package org.jpwh.model.advanced; import java.io.Serializable; import java.math.BigDecim ...
随机推荐
- Querying mergeinfo requires version 3 of the FSFS filesystem schema
环境: jdk 1.7; svn 3.0.4; TortoiseSVN 1.7.13 Subversion 1.7.10; IntelliJ IDEA 13.1.1;win7 64位系统 之前那个 ...
- 20145105 《Java程序设计》第2周学习总结
20145105 <Java程序设计>第2周学习总结 教材学习内容总结 第三章主要的学习内容与c语言有很多相似的地方,讲述了Java的基本语法.其中涵盖: 1. 类型: - short整数 ...
- 如何在Win10下设置图片的浏览方式为windows照片查看器
小编前些天刚装好了win10,一阵心奋啊,今天刚打开一个图片,却发现图片的默认打开方式是window应用商店的app, 这让我觉得特别不舒服,没有之前windows自带的照片查看器好用,后来我本想进入 ...
- poj 2299 求逆序数
#include <iostream> ; int a[MAX]; int swap[MAX]; //临时数组 int n; //数组a的长度 __int64 result; //数组a中 ...
- 【Sum Root to Leaf Numbers】cpp
题目: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a nu ...
- Windows准备Node.js运行与开发环境
如何在Windows环境下搭建Node.js开发环境:1.下载Node.js windows安装版http://www.nodejs.org/download/ 2.正常安装完成后,在系统环境变量已经 ...
- HDU 5446 Unknown Treasure Lucas+中国剩余定理
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446 Unknown Treasure 问题描述 On the way to the next se ...
- vmware workstation 10.0
2013.9.3 vmware workstation 10.0 build 1295980新增功能– 可以将windows 8.1物理pc转变为虚拟机:unity模式增强,与windows 8.1 ...
- 【POJ】【2104】区间第K大
可持久化线段树 可持久化线段树是一种神奇的数据结构,它跟我们原来常用的线段树不同,它每次更新是不更改原来数据的,而是新开节点,维护它的历史版本,实现“可持久化”.(当然视情况也会有需要修改的时候) 可 ...
- Java获取项目中的路径 分类: Java Game 2014-08-14 10:17 122人阅读 评论(0) 收藏
在项目中经常需要获取某个文件的路径: 在这里提供一些获取路径的方法.. 1.此种方式获取的路径,是当前类所在的路径: UserDAOTest.class.getResource("UserD ...