Large Object and Media

A large object (LOB) can be binary or text, and its data is stored in file system instead of database. Large objects are usually attachments of an owning entity.

For example, an Employee can have a number of photos. EmployeePhoto is a LOB.


	@Entity(name="EmployeePhoto")
	@Table(name="EmployeePhoto")
	public class EmployeePhoto extends LobBase implements ChildEntity {
		private Employee employee;

		@Id
		@GeneratedValue(strategy=GenerationType.TABLE, generator="ExampleHR.EPHO_IdGen")
		@TableGenerator(name="ExampleHR.EPHO_IdGen", table="IdGen",
			pkColumnName="entityType", valueColumnName="idValue",
			pkColumnValue="ExampleHR.EPHO", initialValue=1, allocationSize=1)
		public Long getId() {  
			return id;
		}
	
		@ParentEntity
		@ManyToOne
		@JoinColumn(nullable=false, name="employeeId")
		public Employee getEmployee() {
			return employee;
		}

		public void setEmployee(Employee issue) {
			this.employee = issue;
		}
  
		/**
		 * Ordering items within owing entity
		 */
		@Override
		public Integer getSequenceNo() {
		    return sequenceNo;
		}
	
		@Override
		@Column(nullable=false, length=30)
		public String getName() {
			return name;
		}
	
		@Override
		@Column(nullable=false, length=30)
		public String getFileName() {
			return fileName;
		}
	
	}


	public class Employee extends PersistenceEntityBase implements NormativeId {
		...
		private List<EmployeePhoto> photos;
 
	 	@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true, fetch=FetchType.LAZY, 
				mappedBy="employee", targetEntity=EmployeePhoto.class)
		@OrderBy(PersistenceEntity.PROPERTY_SEQUENCE_NO + " ASC")
		public List<EmployeePhoto> getPhotos() {
			return photos;
		}
	
		public void setPhotos(List<EmployeePhoto> photos) {
			this.photos = photos;
		}
	}
EmployeePhoto is ChildEntity. The list of photos are shown as a slideshow using EntityMediaProperty in their owing entity backing bean EmployeeBean.

	@Property(name=Employee.PROPERTY_PHOTOS, 
		view={ViewType.ENTITY, ViewType.ENTITY_LIST_WIDE},
		mode={ModeType.VIEW},
		entityPropertyType=EntityMediaProperty.class,
		renderStyle=@RenderStyleDef(style=RenderStyle.MEDIA))
Large objects are created by uploading files and deleted from their EntityListBackingBean. That is, the media property will be switched to entity list form bean for managing attachments.

If the lobs are not media (image, audio or video), they should be shown as an entity list FormBean.


	@Property(name=Employee.PROPERTY_PHOTOS, 
		view={ViewType.ENTITY},
		entityPropertyType=EntityFormBeanProperty.class)
In the lob list formBean, a file upload dialog can be opened to upload files and create new lob entities. If there is any lob entity that is a media, the slideshow command will switch the formBean to a media property for slideshow. Deleting lob entities will delete their associated lob files on file system.

Lob File Path

Lob data are stored in file system. Default file path is
	[instanceTypeInstance.home]/modules/[module]/[dataTypeName]/[idPath]fileName
For example, an EmployeePhoto whose id is 0a01(hex) and file name is photo1.png. Its file path is:
	[instanceTypeInstance.home]/modules/ExampleHR/EPHO/00/00/0a/01photo1.png
the Id path is hierarchical (4-levels) such as 00/00/0a/01, so Lob files are stored under hierarchical directories.

[instance.home] is the root directory of instance(system or subsystem).

For system: [cmobilecom.home]/files/system
For subsystem: [cmobilecom.home]/files/subsystems/[username]/s[instanceId]

To change lob file path, override getRelativePath() of LobBeanBase. For example,


	public void EmployeePhotoBean extends LobBeanBase<EmployeePhoto> {
	
		@Override
		protected String getRelativePath(EmployeePhoto entity) {
		
		}
	}