Hi Marianne, Unfortunately I don't see anything obviously wrong; can you create a small example github repo that demonstrates the problem?
If that's not possible, perhaps we can do a screenshare to debug together... contact me off-list Thx Dan On 15 April 2015 at 10:38, Marianne Hagaseth < [email protected]> wrote: > Thanks for your reply! > > The app runs using MySQL, I haven't changed anyting there. > The code comes here: > > Best, > Marianne. > > package dom.regulation; > > import java.net.MalformedURLException; > import java.net.URL; > import java.util.*; > import java.util.Collection; > > import javax.jdo.JDOHelper; > import javax.jdo.annotations.IdentityType; > import javax.jdo.annotations.VersionStrategy; > > import com.google.common.base.Objects; > import com.google.common.base.Predicate; > import com.google.common.collect.Ordering; > > import dom.regulation.Regulation.FinalizedEvent; > import dom.regulation.Regulation.RegulationsComparator; > > import org.joda.time.LocalDate; > import org.apache.isis.applib.DomainObjectContainer; > import org.apache.isis.applib.Identifier; > import org.apache.isis.applib.NonRecoverableException; > import org.apache.isis.applib.RecoverableException; > import org.apache.isis.applib.annotation.*; > import org.apache.isis.applib.annotation.ActionSemantics.Of; > import org.apache.isis.applib.annotation.ActionSemantics; > import org.apache.isis.applib.annotation.Disabled; > import org.apache.isis.applib.annotation.ActionInteraction; > import org.apache.isis.applib.annotation.Bulk.AppliesTo; > import org.apache.isis.applib.annotation.Action; > import org.apache.isis.applib.annotation.Bulk; > import org.apache.isis.applib.annotation.CollectionLayout; > import org.apache.isis.applib.annotation.InvokeOn; > import org.apache.isis.applib.annotation.MemberOrder; > import org.apache.isis.applib.annotation.MinLength; > import org.apache.isis.applib.annotation.Named; > import org.apache.isis.applib.annotation.Bookmarkable; > import org.apache.isis.applib.annotation.Optionality; > import org.apache.isis.applib.annotation.Parameter; > import org.apache.isis.applib.annotation.ParameterLayout; > import org.apache.isis.applib.annotation.Property; > import org.apache.isis.applib.annotation.Prototype; > import org.apache.isis.applib.annotation.RenderType; > import org.apache.isis.applib.annotation.Bulk.InteractionContext.InvokedAs; > import org.apache.isis.applib.query.QueryDefault; > import org.apache.isis.applib.security.UserMemento; > import org.apache.isis.applib.services.eventbus.ActionInteractionEvent; > import org.apache.isis.applib.services.eventbus.EventBusService; > import org.apache.isis.applib.services.scratchpad.Scratchpad; > import org.apache.isis.applib.services.wrapper.HiddenException; > import org.apache.isis.applib.services.wrapper.WrapperFactory; > import org.apache.isis.applib.util.ObjectContracts; > import org.apache.isis.applib.util.TitleBuffer; > import org.apache.isis.applib.value.Blob; > import org.apache.isis.applib.value.Clob; > import org.apache.isis.applib.services.clock.ClockService; > > > @javax.jdo.annotations.PersistenceCapable(identityType=IdentityType.DATASTORE) > > @javax.jdo.annotations.DatastoreIdentity( > strategy=javax.jdo.annotations.IdGeneratorStrategy.IDENTITY, > column="id") > @javax.jdo.annotations.Version( > strategy=VersionStrategy.VERSION_NUMBER, > column="version") > @javax.jdo.annotations.Uniques({ > @javax.jdo.annotations.Unique( > name="Rule_description_must_be_unique", > members={"ownedBy","requirement"}) > }) > @javax.jdo.annotations.Queries( { > @javax.jdo.annotations.Query( > name = "findByRule", language = "JDOQL", > value = "SELECT " > + "FROM dom.regulation.Rule " > + "WHERE ownedBy == :ownedBy") > }) > @DomainObject(objectType="RULE", autoCompleteRepository=Rule.class, > autoCompleteAction="autocomplete") > @MemberGroupLayout (columnSpans={6,6,0},left={"Rule",""}, > middle={"General"}) > public class Rule implements Comparable<Rule> { > > //region > LOG > /** > * It isn't common for entities to log, but they can if required. > * Isis uses slf4j API internally (with log4j as implementation), and > is the recommended API to use. > */ > private final static org.slf4j.Logger LOG = > org.slf4j.LoggerFactory.getLogger(Rule.class); > //endregion > > // region > title, icon > public String title() { > final TitleBuffer buf = new TitleBuffer(); > buf.append(getRequirement()); > return buf.toString(); > } > > public String iconName() { > return "done"; > } > //endregion > > > // mhaga: Must be changed to class > // Region: Requirement > private String requirement; > > @javax.jdo.annotations.Column(allowsNull="false", length=1000) > @Property(regexPattern="\\w[@&:\\-\\,\\.\\+ \\w]*") > @MemberOrder(name="Requirement", sequence="10") > @PropertyLayout(typicalLength=100) > public String getRequirement() { > return requirement; > } > > public void setRequirement(final String requirement) { > this.requirement = requirement; > } > public void modifyRequirement(final String requirement) { > setRequirement(requirement); > } > public void clearRequirement() { > setRequirement(null); > } > //endregion Requirement > > // mhaga: Must be changed to class > // Region: Target > private String target; > > @javax.jdo.annotations.Column(allowsNull="false", length=1000) > @Property(regexPattern="\\w[@&:\\-\\,\\.\\+ \\w]*") > @MemberOrder(name="Requirement", sequence="20") > @PropertyLayout(typicalLength=100) > public String getTarget() { > return target; > } > > public void setTarget(final String target) { > this.target = target; > } > public void modifyTarget(final String target) { > setTarget(target); > } > public void clearTarget() { > setTarget(null); > } > //endregion Target > > > // mhaga: Must be changed to class > // Region: Context > private String context; > > @javax.jdo.annotations.Column(allowsNull="true", length=1000) > @Property(regexPattern="\\w[@&:\\-\\,\\.\\+ \\w]*") > @MemberOrder(name="Requirement", sequence="30") > @PropertyLayout(typicalLength=100) > public String getContext() { > return context; > } > > public void setContext(final String context) { > this.context = context; > } > public void modifyContext(final String context) { > setContext(context); > } > public void clearContext() { > setContext(null); > } > //endregion Context > > // mhaga: Must be changed to class > // Region: Exception > private String exception; > > @javax.jdo.annotations.Column(allowsNull="true", length=1000) > @Property(regexPattern="\\w[@&:\\-\\,\\.\\+ \\w]*") > @MemberOrder(name="Requirement", sequence="40") > @PropertyLayout(typicalLength=100) > public String getException() { > return context; > } > > public void setException(final String exception) { > this.exception = exception; > } > public void modifyException(final String exception) { > setException(exception); > } > public void clearException() { > setException(null); > } > //endregion Exception > > > > // region Mandatory (property) > @javax.jdo.annotations.Column(allowsNull="false") > private boolean mandatory; > @MemberOrder(sequence="50") > > public boolean getMandatory() { > return mandatory; > } > > public void setMandatory(final boolean mandatory) { > this.mandatory = mandatory; > } > // end region > > //region DisjunctRequirement (property) > @javax.jdo.annotations.Column(allowsNull="true") > private boolean disjunctRequirement; > @MemberOrder(sequence="60") > > public boolean getDisjunctRequirement() { > return disjunctRequirement; > } > > public void setDisjunctRequirement(final boolean disjunctRequirement) { > this.disjunctRequirement = disjunctRequirement; > } > //end region > > > // mhaga: Must be changed to class > // Region: Type > public enum RuleType { > RuleType1, > RuleType2} > > private RuleType type; > > @javax.jdo.annotations.Column(allowsNull="true", length=255) > @Property(regexPattern="\\w[@&:\\-\\,\\.\\+ \\w]*") > @MemberOrder(name="Requirement", sequence="70") > @PropertyLayout(typicalLength=100) > public RuleType getType() { > return type; > } > > public void setType(final RuleType type) { > this.type = type; > } > public void modifyType(final RuleType type) { > setType(type); > } > public void clearType() { > setType(null); > } > //endregion Type > > > //region > ownedBy (property) > > private String ownedBy; > @PropertyLayout(hidden=Where.EVERYWHERE) > @ActionLayout(hidden=Where.EVERYWHERE) > @javax.jdo.annotations.Column(allowsNull="true") > public String getOwnedBy() { > return ownedBy; > } > @ActionLayout(hidden=Where.EVERYWHERE) > @javax.jdo.annotations.Column(allowsNull="true") > public void setOwnedBy(final String ownedBy) { > this.ownedBy = ownedBy; > } > //endregion > > //region > Subject:list of key words fetched from Luxid (property) > private String subject; > @javax.jdo.annotations.Column(allowsNull="true", length=255) > @MemberOrder(name="Free Text Paragraph", sequence="90") > @Property(editing= Editing.DISABLED,editingDisabledReason="Subject is > a list of keywords fetched from Luxid: Cannot be edited") > public String getSubject() { > return subject; > } > @javax.jdo.annotations.Column(allowsNull="true", length=255) > public void setSubject(final String subject) { > this.subject = subject; > } > //endregion > > > > //region > version (derived property) > public Long getVersionSequence() { > if(!(this instanceof javax.jdo.spi.PersistenceCapable)) { > return null; > } > javax.jdo.spi.PersistenceCapable persistenceCapable = > (javax.jdo.spi.PersistenceCapable) this; > final Long version = (Long) > JDOHelper.getVersion(persistenceCapable); > return version; > } > // hide property (imperatively, based on state of object) > public boolean hideVersionSequence() { > return !(this instanceof javax.jdo.spi.PersistenceCapable); > } > //endregion > > > > //region > delete (action) > @Action(domainEvent=DeletedEvent.class, invokeOn = > InvokeOn.OBJECT_AND_COLLECTION) > // @Bulk > public List<Rule> delete() { > > container.removeIfNotAlready(this); > > container.informUser("Deleted " + > container.titleOf(this)); > return container.allMatches( > new QueryDefault<Rule>(Rule.class, > "findByRule", > "ownedBy", container.getUser().getName()) > ); > } > //endregion > > > > //region > lifecycle callbacks > > public void created() { > LOG.debug("lifecycle callback: created: " + this.toString()); > } > > public void loaded() { > LOG.debug("lifecycle callback: loaded: " + this.toString()); > } > > public void persisting() { > LOG.debug("lifecycle callback: persisting: " + this.toString()); > } > > public void persisted() { > LOG.debug("lifecycle callback: persisted: " + this.toString()); > } > > public void updating() { > LOG.debug("lifecycle callback: updating: " + this.toString()); > } > public void updated() { > LOG.debug("lifecycle callback: updated: " + this.toString()); > } > > public void removing() { > LOG.debug("lifecycle callback: removing: " + this.toString()); > } > > public void removed() { > LOG.debug("lifecycle callback: removed: " + this.toString()); > } > //endregion > > //region > events > > @SuppressWarnings("deprecation") > public static abstract class AbstractActionInteractionEvent > extends ActionInteractionEvent<Rule> { > private static final long serialVersionUID = 1L; > private final String description; > public AbstractActionInteractionEvent( > final String description, > final Rule source, > final Identifier identifier, > final Object... arguments) { > super(source, identifier, arguments); > this.description = description; > } > public String getEventDescription() { > return description; > } > } > > > public static class FinalizedEvent extends > AbstractActionInteractionEvent { > private static final long serialVersionUID = 1L; > public FinalizedEvent( > final Rule source, > final Identifier identifier, > final Object... arguments) { > super("finalized", source, identifier, arguments); > } > } > > public static class NoLongerFinalizedEvent extends > AbstractActionInteractionEvent { > private static final long serialVersionUID = 1L; > public NoLongerFinalizedEvent( > final Rule source, > final Identifier identifier, > final Object... arguments) { > super("no longer finalized", source, identifier, arguments); > } > } > > public static class DeletedEvent extends > AbstractActionInteractionEvent { > private static final long serialVersionUID = 1L; > public DeletedEvent( > final Rule source, > final Identifier identifier, > final Object... arguments) { > super("deleted", source, identifier, arguments); > } > } > > //endregion > > //region > predicates > > public static class Predicates { > > public static Predicate<Rule> thoseOwnedBy(final String > currentUser) { > return new Predicate<Rule>() { > @Override > public boolean apply(final Rule rule) { > return Objects.equal(rule.getOwnedBy(), currentUser); > } > }; > } > } > > //endregion > > //region > toString, compareTo > @Override > public String toString() { > // This must match the autocomplete stuff > return ObjectContracts.toString(this, "requirement, > target,context, exception, mandatory, disjunctRequirement, type,subject, > ownedBy"); > } > > /** > * Required so can store in {@link SortedSet sorted set}s (eg {@link > #getDependencies()}). > */ > @Override > public int compareTo(final Rule other) { > > return ObjectContracts.compare(this, other, "requirement, > target,context, exception, mandatory, disjunctRequirement, type,subject, > ownedBy"); > } > //endregion > > //region > injected services > @javax.inject.Inject > private DomainObjectContainer container; > > > @javax.inject.Inject > private Rules rules; > > > @SuppressWarnings("deprecation") > Bulk.InteractionContext bulkInteractionContext; > public void > injectBulkInteractionContext(@SuppressWarnings("deprecation") > Bulk.InteractionContext bulkInteractionContext) { > this.bulkInteractionContext = bulkInteractionContext; > } > > @javax.inject.Inject > > EventBusService eventBusService; > public void injectEventBusService(EventBusService eventBusService) { > this.eventBusService = eventBusService; > } > > @javax.inject.Inject > private WrapperFactory wrapperFactory; > > //endregion > > } > > > -----Original Message----- > From: Dan Haywood [mailto:[email protected]] > Sent: 14. april 2015 22:41 > To: users > Subject: Re: MySQL and "Specified key was too long" > > I suspect that you'll find that the Rule class already has a > @PersistenceCapable annotation; otherwise you wouldn't have seen any DDL > for the "create table rule". > > I was going to say that I thought that the DataNuclues enhancer hasn't > correctly run, but I think that usually manifests itself as some other > problem. > > Even so, I do think that, somehow, DN is trying to serialize the Rule > instance rather than store the rule's Id as a foreign key. > > Two questions: > - can you post the full source code for the Rule class? > - does the app run using hsqldb:mem (rather than MySQL). > > Thx > Dan > > > > On 14 April 2015 at 22:15, Martin Grigorov <[email protected]> wrote: > > > Hi, > > > > You should annotate Rule class with @PersistenceCapable as > > SimpleObject > > does: > > > > https://github.com/apache/isis/blob/c3740b13177e4db7d7cafae3c1dd839b99 > > 7fc806/example/application/simpleapp/dom/src/main/java/domainapp/dom/m > > odules/simple/SimpleObject.java#L38 > > > > Martin Grigorov > > Freelancer, available for hire! > > Wicket Training and Consulting > > https://twitter.com/mtgrigorov > > > > On Tue, Apr 14, 2015 at 4:16 PM, Marianne Hagaseth < > > [email protected]> wrote: > > > > > But how do I annotate the Rule class as @PersistenceCapable ? > > > > > > -----Original Message----- > > > From: Dan Haywood [mailto:[email protected]] > > > Sent: 20. mars 2015 10:42 > > > To: users > > > Subject: Re: MySQL and "Specified key was too long" > > > > > > Hi Marianne, > > > > > > My *guess* is that the Rule class is not annotated as > > > @PersistenceCapable but is serializable, and so DataNucleus is > > > serializing the object as a byte[] array, and that is overflowing the > limit for MySQL. > > > > > > Double check what the schema is that's being created; you can get DN > > > to log this by setting: > > > > > > log4j.logger.DataNucleus.Datastore.Schema=DEBUG, Console > > > > > > in WEB-INF/logging.properties . > > > > > > You could also set: > > > > > > log4j.logger.DataNucleus.Datastore.Native=DEBUG, Console > > > > > > in order to inspect the SQL INSERT statement. > > > > > > Let us know how you get on. > > > > > > Cheers > > > Dan > > > > > > > > > > > > > > > On 20 March 2015 at 09:35, Marianne Hagaseth < > > > [email protected]> wrote: > > > > > > > Hi there, > > > > I am trying to add this property (see code further down) and then > > > > using mySQL for the persistence. > > > > However, it fails with a MySQL error: "Specified key was too long; > > > > max key length is 767 bytes" > > > > > > > > Anyone who have ideas for where to start searching for the error? > > > > > > > > Best, > > > > Marianne Hagaseth. > > > > > > > > //region > rule (property) > > > > private Rule rule; > > > > @javax.jdo.annotations.Column(name="ruleId",allowsNull="true") > > > > @MemberOrder(name="General", sequence="80") > > > > public Rule getRule() { > > > > return rule; > > > > } > > > > public void setRule(final Rule rule) { > > > > this.rule = rule; > > > > } > > > > //endregion > > > > > > > > > > > > > > > > 10:20:45,861 [Schema main DEBUG] Execution > Time = > > > > 123 ms > > > > 10:20:45,865 [Datastore main ERROR] An exception > was > > > > thrown while adding/validating class(es) : Specified key was too > > > > long; max key length is 767 bytes > > > > com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: > > > > Specified key was too long; max key length is 767 bytes > > > > at > > > > sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native > > > > Method) > > > > at > > > > > > > > > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructo > > rAccessorImpl.java:57) > > > > at > > > > > > > > > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingCo > > nstructorAccessorImpl.java:45) > > > > at > > > > java.lang.reflect.Constructor.newInstance(Constructor.java:526) > > > > > > > > > > > > at org.mortbay.jetty.Server.doStart(Server.java:224) > > > > at > > > > > > org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:5 > > 0) > > > > at > > > > > > > > > org.apache.isis.core.webserver.WebServerBootstrapper.bootstrap(WebServ > > erBootstrapper.java:85) > > > > at > > > org.apache.isis.core.webserver.WebServer.run(WebServer.java:103) > > > > at > > > org.apache.isis.core.webserver.WebServer.main(WebServer.java:67) > > > > at org.apache.isis.WebServer.main(WebServer.java:25) > > > > > > > > 10:20:45,865 [Datastore main ERROR] An exception > was > > > > thrown while adding/validating class(es) : Specified key was too > > > > long; max key length is 767 bytes > > > > com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: > > > > Specified key was too long; max key length is 767 bytes > > > > at > > > > sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native > > > > Method) > > > > at > > > > > > > > > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructo > > rAccessorImpl.java:57) > > > > at > > > > > > > > > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingCo > > nstructorAccessorImpl.java:45) > > > > at > > java.lang.reflect.Constructor.newInstance(Constructor.java:526) > > > > at com.mysql.jdbc.Util.handleNewInstance(Util.java:377) > > > > at com.mysql.jdbc.Util.getInstance(Util.java:360) > > > > at > > > > com.mysql.jdbc.SQLError.createSQLException(SQLError.java:978) > > > > > > > > > > > > Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: > > > > Specified key was too long; max key length is 767 bytes > > > > at > > > > sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native > > > > Method) > > > > at > > > > > > > > > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructo > > rAccessorImpl.java:57) > > > > at > > > > > > > > > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingCo > > nstructorAccessorImpl.java:45) > > > > at > > java.lang.reflect.Constructor.newInstance(Constructor.java:526) > > > > ... 54 more > > > > 10:20:46,204 [WicketFilter main ERROR] The > > initialization > > > > of an application with name 'WicketFilter' has failed. > > > > com.google.inject.ProvisionException: Guice provision errors: > > > > > > > > 1) Error in custom provider, > > > > org.datanucleus.exceptions.NucleusDataStoreException: Error(s) > > > > were found while auto-creating/validating the datastore for > > > > classes. The errors are printed in the log, and are attached to this > exception. > > > > at > > > > org.apache.isis.core.runtime.runner.IsisInjectModule.provideIsisSy > > > > stem > > > > (IsisInjectModule.java:132) > > > > > > > > > > > > //region > rule (property) > > > > private Rule rule; > > > > @javax.jdo.annotations.Column(name="ruleId",allowsNull="true") > > > > @MemberOrder(name="General", sequence="80") > > > > public Rule getRule() { > > > > return rule; > > > > } > > > > public void setRule(final Rule rule) { > > > > this.rule = rule; > > > > } > > > > //endregion > > > > > > > > > > > > > > > > > >
