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
> > >
> > >
> > >
> >
>