I am using:
- a Mapped Superclass for all basic entities (MIPEntity)
- a pre persist entity listener to change some values
- the following hierarchy: MIPEntity<-ObjectItem<-Organisation
- a more complex association for associating Organisations
- OpenJPA 2.0 (JPA 2.0) with compile time class enhancement
- JPAExtension on Github
Some example queries:
Delete all Object Items and insert a new one:
withTrxAndCommit { createQuery("Delete from ObjectItem") executeUpdate val item = new ObjectItem() . . . persist(item) }
Query for ObjectItem and return the first object:
withNoTrx { val oiList = createQuery[ObjectItem]("Select oi from ObjectItem oi").getResultList oiList.head }
Apply function on query results. Using query with id FindObjectItemFromName and query parameter %Test%. The type is inferred from the term oi: ObjectItem.
forQueryResults { oi: ObjectItem => . . . // do something with oi } withQuery (QueryId("FindObjectItemFromName"), "%Test%")
Same with filter object (for type-safe usage of binding parameter):
val filter = newFilterInstance[NameFilter](QueryId("FindObjectItemFromNameWithFilter")) filter.name = "%Test%" //set binding parameter var i: Int = 0 forQueryResults { oi: ObjectItem => . . . // do something with oi } withQuery (filter)
Apply function on entity got by find (BigInteger as primary key). Type is inferred by oi: ObjectItem again:
findAndApply(id) { oi: ObjectItem => . . . // do something with oi }
Example Scala Entities
Mapped Superclass MIPEntity
Class whose mapping information is applied to the entities that inherit from it.
@MappedSuperclass @EntityListeners(Array(classOf[MIPEntityInterceptor])) class MIPEntity { @Column(name = "creator_id", nullable = false, length = 20) @BeanProperty protected var creatorId: BigInteger = _ @Column(name = "update_seqnr", nullable = false, length = 15) @BeanProperty protected var updateSeqNr: Long = _ }
Entity Listener
Specifies the callback listener classes to be used for an entity or mapped superclass. Resets both MIPEntity values to some values.
class MIPEntityInterceptor { @PrePersist def prePersist(entity: MIPEntity): Unit = { entity.setUpdateSeqNr(1234L) entity.setCreatorId(BigInteger.valueOf(815)) } }
Object Item Entity
Uses inheritance strategy joined and a sequence for primary key
@Entity @Table(name = "obj_item") @Inheritance(strategy = InheritanceType.JOINED) @SequenceGenerator(name = "obj_item_id_seq", sequenceName = "obj_item_id_sequence", allocationSize = 1) class ObjectItem extends MIPEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "obj_item_id_seq") @Column(name = "obj_item_id", nullable = false, length = 20) @BeanProperty var id: BigInteger = _ @Column(name = "cat_code", nullable = false, length = 6) @BeanProperty var objItemCatCode: String = _ }
Organisation Entity
@Entity @Table(name = "org") @PrimaryKeyJoinColumn(name = "org_id") class Organisation extends ObjectItem { @Column(name = "cat_code", length = 6, nullable = false) @BeanProperty var orgCatCode: String = _ }
Using Id Class Identity
More complex association using Id Class for Entity Identity Fields.
@Entity @Table(name = "org_struct") @IdClass(classOf[OrganisationStructureId]) @SequenceGenerator(name = "org_struct_index_seq", sequenceName = "org_struct_index_sequence", allocationSize = 1) class OrganisationStructure extends MIPEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "org_struct_index_seq") @Column(name = "org_struct_ix", nullable = false, length = 20) @BeanProperty protected var ix: BigInteger = _ @Id @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "org_struct_root_org_id", nullable = false, updatable = false) @BeanProperty protected var orgStructRootOrg: Organisation = _ @Column(name = "name_txt", length = 100) @BeanProperty protected var nameTxt: String = _ }
Id Class for Entity Identity Fields:
class OrganisationStructureId { @BeanProperty var orgStructRootOrg: BigInteger = _ @BeanProperty var ix: BigInteger = _ override def equals(obj: Any): Boolean = . . . override def hashCode = . . . }