001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.connector.store.jpa.model.basic; 025 026 import javax.persistence.Column; 027 import javax.persistence.Entity; 028 import javax.persistence.EntityManager; 029 import javax.persistence.EnumType; 030 import javax.persistence.Enumerated; 031 import javax.persistence.Id; 032 import javax.persistence.Lob; 033 import javax.persistence.NamedQuery; 034 import javax.persistence.Query; 035 import javax.persistence.Table; 036 import org.jboss.dna.graph.property.PropertyType; 037 038 /** 039 * A single property value that is too large to be stored on the individual node, and which will be shared among all properties 040 * that have the same value. Note that the large values are stored independently of workspace, so one large value may be shared by 041 * properties of nodes in different workspaces. 042 * 043 * @author Randall Hauch 044 */ 045 @Entity 046 @Table( name = "DNA_BASIC_LARGE_VALUES" ) 047 @NamedQuery( name = "LargeValueEntity.deleteUnused", query = "delete LargeValueEntity value where value.id not in (select values.hash from PropertiesEntity prop join prop.largeValues values)" ) 048 public class LargeValueEntity { 049 050 @Id 051 private LargeValueId id; 052 053 /** 054 * The property type for this value. Typically, this is {@link PropertyType#STRING} or {@link PropertyType#BINARY}, although 055 * technically it could be any type. 056 */ 057 @Enumerated( value = EnumType.STRING ) 058 @Column( name = "TYPE", nullable = false ) 059 private PropertyType type; 060 061 /** 062 * The number of bytes in this value. 063 */ 064 @Column( name = "LENGTH", nullable = false ) 065 private long length; 066 067 /** 068 * Flag specifying whether the binary data is stored in a compressed format. 069 */ 070 @Column( name = "COMPRESSED", nullable = true ) 071 private Boolean compressed; 072 073 /** 074 * Lazily-fetched value 075 */ 076 @Lob 077 @Column( name = "DATA", nullable = false ) 078 private byte[] data; 079 080 /** 081 * @return id 082 */ 083 public LargeValueId getId() { 084 return id; 085 } 086 087 /** 088 * @param id Sets id to the specified value. 089 */ 090 public void setId( LargeValueId id ) { 091 this.id = id; 092 } 093 094 /** 095 * @return length 096 */ 097 public long getLength() { 098 return length; 099 } 100 101 /** 102 * @param length Sets length to the specified value. 103 */ 104 public void setLength( long length ) { 105 this.length = length; 106 } 107 108 /** 109 * @return type 110 */ 111 public PropertyType getType() { 112 return type; 113 } 114 115 /** 116 * @param type Sets type to the specified value. 117 */ 118 public void setType( PropertyType type ) { 119 this.type = type; 120 } 121 122 /** 123 * @return data 124 */ 125 public byte[] getData() { 126 return data; 127 } 128 129 /** 130 * @param data Sets data to the specified value. 131 */ 132 public void setData( byte[] data ) { 133 this.data = data; 134 } 135 136 /** 137 * @return compressed 138 */ 139 public boolean isCompressed() { 140 return compressed != null && compressed.booleanValue(); 141 } 142 143 /** 144 * @param compressed Sets compressed to the specified value. 145 */ 146 public void setCompressed( boolean compressed ) { 147 this.compressed = Boolean.valueOf(compressed); 148 } 149 150 /** 151 * {@inheritDoc} 152 * 153 * @see java.lang.Object#hashCode() 154 */ 155 @Override 156 public int hashCode() { 157 return id.hashCode(); 158 } 159 160 /** 161 * {@inheritDoc} 162 * 163 * @see java.lang.Object#equals(java.lang.Object) 164 */ 165 @Override 166 public boolean equals( Object obj ) { 167 if (obj == this) return true; 168 if (obj instanceof LargeValueEntity) { 169 LargeValueEntity that = (LargeValueEntity)obj; 170 if (this.getId().equals(that.getId())) return true; 171 } 172 return false; 173 } 174 175 /** 176 * {@inheritDoc} 177 * 178 * @see java.lang.Object#toString() 179 */ 180 @Override 181 public String toString() { 182 return "Large " + this.type + " value (hash=" + this.getId().getHash() + ",compressed=" + isCompressed() + ")"; 183 } 184 185 /** 186 * Delete all unused large value entities. 187 * 188 * @param manager the manager; never null 189 * @return the number of deleted large values 190 */ 191 public static int deleteUnused( EntityManager manager ) { 192 assert manager != null; 193 Query delete = manager.createNamedQuery("LargeValueEntity.deleteUnused"); 194 int result = delete.executeUpdate(); 195 manager.flush(); 196 return result; 197 } 198 }