the issue don't produce stackTrace, only message from JVM. Here is it:
Code:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 131072000 bytes for GrET in C:\BUILD_AREA\jdk6_17\hotspot\src\share\vm\utilities\growableArray.cpp. Out of swap space?
#
# Internal Error (allocation.inline.hpp:39), pid=4560, tid=5348
# Error: GrET in C:\BUILD_AREA\jdk6_17\hotspot\src\share\vm\utilities\growableArray.cpp
#
# JRE version: 6.0_17-b04
# Java VM: Java HotSpot(TM) Client VM (14.3-b01 mixed mode windows-x86 )
# An error report file with more information is saved as:
# C:\SintecDevel\workspace\OnBoard\hs_err_pid4560.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
The message contains version of JVM and JRE. I'm run it on WindowsXP 32-bit with 3.5G of RAM and 300G of hard disk. Before the test I have 2.5G of RAM free and 250G free on hard disk.
The test executed from eclipse with '-Xmx1200M' argument. I've also find in one of the forums that '-Xss512k' can help and added it.
The index started with this code:
Code:
//Load hibernate configuration and receiving hibernate search session
Configuration config =
new AnnotationConfiguration().configure( "hibernatealone.cfg.xml" );
config.setNamingStrategy( ImprovedNamingStrategy.INSTANCE );
SessionFactory sessions = config.buildSessionFactory();
Session session = sessions.openSession();
FullTextSession fullTextSession = Search.getFullTextSession( session );
boolean result = false;
//Building index
Date date = new Date();
System.out.println(
"Starting to build Lucene index for Hibernate Search: " + date );
try {
fullTextSession.createIndexer().batchSizeToLoadObjects( 1
).threadsForSubsequentFetching( 1
).threadsToLoadObjects( 1
).cacheMode( CacheMode.IGNORE
).startAndWait();
result = true;
} catch( Exception e) {
result = false;
}
fullTextSession.getSessionFactory().close();
System.out.println(
( result ? "Success" : "Error" ) +
" building Lucene index for Hibernate Search. " +
( new Date().getTime() - date.getTime() ) + " ms" );
hibernatealone.cfg.xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/tesths?autoReconnect=true</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.username">test</property>
<property name="hibernate.connection.password">test</property>
<property name="hibernate.show_sql">false</property>
<!-- property name="hibernate.hbm2ddl.auto">validate</property -->
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider</property>
<property name="hibernate.search.default.indexBase">C:\\workspace\\Test\\HibernateSearch\\indexes</property>
<property name="hibernate.search.default.exclusive_index_use">true</property>
<mapping class="com.mycompany.Groups" />
<mapping class="com.mycompany.model.Company" />
<mapping class="com.mycompany.model.CompanyType" />
<mapping class="com.mycompany.model.Role" />
<mapping class="com.mycompany.model.User" />
<mapping class="com.mycompany.model.PrefixCurrency" />
<mapping class="com.mycompany.model.PrefixLang" />
<mapping class="com.mycompany.model.PrefixTimezone" />
<mapping class="com.mycompany.model.DatePatternType" />
<mapping class="com.mycompany.model.View" />
<mapping class="com.mycompany.model.ObjectPermission" />
<mapping class="com.mycompany.model.ObjectEntryPermission" />
<mapping class="com.mycompany.model.ObjectClass" />
<mapping class="com.mycompany.model.SpotOrder" />
<mapping class="com.mycompany.model.ObjectEntry" />
</session-factory>
</hibernate-configuration>
There are many indexed classes, but only SpotOrders has 30 million records and fails. I see in log that indexing fails on this table. Morever, other classes has maximum 100 records, so I give here only code for classes related to SpotOrders. If you want to see additional classes write in forum and I'll give it too. May be it will be better if I'll attach sources to topic, but I don't know how do it in this forum.
Code:
@MappedSuperclass
public abstract class BaseEntityImpl extends HashCodeValidator
implements BaseEntity {
private static final long serialVersionUID = 1645059492245740266L;
@Override
@Transient
@Fields( {
@Field( index=Index.TOKENIZED, store=Store.NO ),
@Field( name="free_search", index=Index.TOKENIZED, store=Store.NO ) } )
public Class<?> getClassType() {
return
( this instanceof HibernateProxy ) ?
this.getClass().getSuperclass() : this.getClass();
}
@Override
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(precision = 10, unique = true, nullable = false, updatable = false)
public Long getId() {
return super.getId();
}
@Override
public void setId(Long id) {
super.setId(id);
}
}
Code:
@MappedSuperclass
public abstract class CompanyBasedSearchEntity extends BaseEntityImpl
implements BaseEntity {
private static final long serialVersionUID = 3953368748208085084L;
@Fields( {
@Field( index=Index.TOKENIZED, store=Store.NO ),
@Field( name="free_search", index=Index.TOKENIZED, store=Store.NO ) } )
@FieldBridge(impl = CompanyBridge.class)
@ManyToOne( cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@JoinColumn(name = "company_id", nullable = true )
public Company getCompany(){ return company; };
public void setCompany( Company company ){ this.company = company; }
protected Company company;
}
Code:
@Entity
@Table(name = "spot_orders")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Indexed
public class SpotOrder extends CompanyBasedSearchEntity implements Searchable {
private static final long serialVersionUID = -1493851936988449752L;
@Fields( {
@Field( index=Index.TOKENIZED, store=Store.NO ),
@Field( name="free_search", index=Index.TOKENIZED, store=Store.NO ) } )
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
private String name;
}
Code:
@Entity
@Table(name = "users")
@Indexed
@FullTextFilterDefs( {
@FullTextFilterDef(
name = "securityFilter", impl = SecurityFilterFactory.class ),
@FullTextFilterDef(
name = "companyFilter", impl = CompanyFilterFactory.class )
} )
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User extends CompanyBasedSearchEntity
implements Searchable, Comparable<User> {
private static final long serialVersionUID = -559024047L;
private Boolean enabled;
private Boolean status;
private String name;
private String password;
private PrefixTimezone timeZone;
private String defaultPattern;
private String imageUrl = "sampleFace.jpg";
public User() {}
public User(Long id) { setId(id); }
@ManyToMany(
fetch = FetchType.EAGER,
cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH} )
@JoinTable(
name = "group_members",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "group_id") )
@IndexedEmbedded
public Set<Groups> getGroups() { return groups; }
public void setGroups(Set<Groups> groups) {
this.groups = groups;
}
private Set<Groups> groups;
@Transient
public Set<Role> getRoles() {
Set<Role> roles = new HashSet<Role>();
if (groups != null) {
for (Groups group : groups) {
roles.addAll((group.getRoles()));
}
}
return roles;
};
@Transient
public Set<View> getViews() {
Set<View> views = new HashSet<View>();
Set<Role> roles = getRoles();
for (Role role : roles) {
views.addAll((role.getViews()));
}
return views;
};
@Transient
@IndexedEmbedded
public Set<ObjectPermission> getObjectPermissions() {
Set<ObjectPermission> perms = new HashSet<ObjectPermission>();
Set<Role> roles = getRoles();
for( Role role : roles ) {
perms.addAll( role.getObjectPermissions().values() );
}
return perms;
};
public Boolean isEnabled() { return this.enabled; }
public void setEnabled(final Boolean enabled) { this.enabled = enabled; }
public Boolean isStatus() { return status; }
public void setStatus(final Boolean status) { this.status = status; }
@Column(length = 45)
@Fields( {
@Field( index=Index.TOKENIZED, store=Store.NO ),
@Field( name="free_search", index=Index.TOKENIZED, store=Store.NO ) } )
public String getName() { return this.name; }
public void setName(final String name) { this.name = name; }
public String getPassword() { return this.password; }
public void setPassword(final String password) { this.password = password; }
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
@JoinColumn(name = "time_zone_id", nullable = true)
public PrefixTimezone getTimeZone() {
return this.timeZone == null ? getCompany().getTimeZone() : this.timeZone;
}
public void setTimeZone(final PrefixTimezone timeZone) { this.timeZone = timeZone; }
@Column(name = "default_pattern")
@Fields( {
@Field( index=Index.TOKENIZED, store=Store.NO ),
@Field( name="free_search", index=Index.TOKENIZED, store=Store.NO ) } )
public String getDefaultPattern() { return defaultPattern; }
public void setDefaultPattern(String defaultPattern) {
this.defaultPattern = defaultPattern;
}
@Column(name = "image_url")
@Fields( {
@Field( index=Index.TOKENIZED, store=Store.NO ),
@Field( name="free_search", index=Index.TOKENIZED, store=Store.NO ) } )
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
@Transient
public Boolean getEnabled() { return this.enabled; }
@Override
public int compareTo(User other) { return name.compareTo(other.getName()); }
@Override
public String toString(){ return name; }
}