#1242 confirmed
Andrea

renderJSON and @OneToMany

Reported by Andrea | November 12th, 2011 @ 11:36 AM | in 1.4.x

Framework version:1.2.3
Platform you're using:MAc OS X

Reproduction steps:
create a model like:

@Entity
public class Manifacturers extends TempModel {

    public String company;
    public String infos;

    @OneToMany(cascade=CascadeType.PERSIST, targetEntity=Models.class,mappedBy="manifacturer")
    public List<Models> models; 
}

and another model like

@Entity
public class Models extends TempModel {

    @ManyToOne(cascade=CascadeType.PERSIST, fetch=FetchType.LAZY,targetEntity=Manifacturers.class)
    public Manifacturers manifacturer;

    @OneToMany(cascade=CascadeType.PERSIST, targetEntity=Terminals.class,mappedBy="model")
    public List<Terminals> terminal;

    public String name;     
}

from the controller i call:

public static void getPhoneModels(Long id){
        Manifacturers manifacturer = Manifacturers.findById(id);
        renderJSON(manifacturer);
}

and the return value is

llegalStateException occured : circular reference error Offending field: manifacturer Offending object: preserveType: false, type: class models.phones.Manifacturers, obj: Manifacturers[1]

Comments and changes to this ticket

  • Andrea

    Andrea November 12th, 2011 @ 11:45 AM

    i now that the problem is for @OneToMany and GSON.
    but have in the roadmap a solution for this problem?

  • Ali Lozano

    Ali Lozano November 12th, 2011 @ 05:30 PM

    The solution can be add a exclusion by annotation @OneToMany to gson object.

  • Andrea

    Andrea November 12th, 2011 @ 11:28 PM

    could you show some example please.

    i have solved the problem with other JSON serializer

    thank's

  • Ali Lozano

    Ali Lozano November 13th, 2011 @ 10:52 PM

    See the Gson documentation, https://sites.google.com/site/gson/gson-user-guide#TOC-User-Defined...

    You can create a exclusion strategie that exclude the @OneToMany anotation, it can be:

    public class RelationExclusions implements ExclusionStrategy {

    public boolean shouldSkipClass(Class<?> clazz) {
      return false;
    }
    
    public boolean shouldSkipField(FieldAttributes f) {
      return f.getAnnotation(OneToMany.class) != null;
    }
    

    }

    And for use, you can do something like this:

    renderText(new GsonBuilder().setExclusionStrategies(new RelationExclusions()).create().toJson(obj);

  • Nicolas Leroux

    Nicolas Leroux November 14th, 2011 @ 08:19 PM

    • Assigned user set to “Peter Hilton”
    • State changed from “new” to “opinion”
    • Milestone set to 1.3
    • Milestone order changed from “886” to “0”

    I don't think we can do that in play core. Maybe the proposed solution can be added to the documentation?

  • Andrea

    Andrea November 14th, 2011 @ 10:13 PM

    probably a documentation update with this solution will be a good start.
    but have some questions to add.
    why we need to use something, that use lot of code when with FlexJson i can solve it with two lines.

    public class Test extends Controller {
    
        /**
         * AJAX section
         */
        public static void getPhoneModels(Long id){
            Manifacturers manifacturer = Manifacturers.findById(id);
            //the FlexJson serializer
            JSONSerializer manifacturersSerializer = new JSONSerializer().include("company","models.id","models.name").exclude("*");
            renderJSON(manifacturersSerializer.serialize(manifacturer));
        }
    }
    

    something strange, you don't think?

    thank's Ali for your help, i have very appreciated :-)
    Thank's Nicolas.....

  • Peter Hilton

    Peter Hilton November 15th, 2011 @ 04:23 PM

    why we need to use something, that use lot of code when with FlexJson i can solve it with two lines

    There are various pros and cons between GSON and FlexJSON, and for whatever reason, Play uses GSON. For example, there is more discussion of FlexJSON at http://www.lunatech-research.com/archives/2011/04/20/play-framework...

    If more people want to use FlexJSON, then the correct approach is to provide it as an alternative implementation via a Play module.

  • Peter Hilton

    Peter Hilton November 16th, 2011 @ 09:30 AM

    • State changed from “opinion” to “confirmed”
    • Tag set to documentation
  • Mariusz Nosinski

    Mariusz Nosinski September 14th, 2012 @ 12:31 PM

    I'm Using another solution, maybe it can be attached to Play!sources

    First I have declared annotation:

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.METHOD})
    public @interface DontSerialize {
    }
    

    and own exlusion strategy:

    public class GsonExclusionStrategy implements ExclusionStrategy {
    
        private final Class<?> typeToExclude;
    
        public boolean shouldSkipField(FieldAttributes fieldAttributes) {
    
            return fieldAttributes.getAnnotation(DontSerialize.class) != null;
        }
    
        public boolean shouldSkipClass(Class<?> aClass) {
    
            return (this.typeToExclude != null && this.typeToExclude == aClass)
                    || aClass.getAnnotation(DontSerialize.class) != null;
        }
    
        public GsonExclusionStrategy(Class<?> typeToExclude) {
    
            this.typeToExclude = typeToExclude;
        }
    }
    

    Fields or classes annotated with this annotation will be skipped on models serialization.

    model:

    public class Item extends Model {
    
    public String name; //serialize
    
    @DontSerialize
    public String veryimportantInfo;
    }
    

    in controller:

    GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.setExclusionStrategies(new GsonExclusionStrategy(null));
            Gson gson = gsonBuilder.serializeNulls().create();
    
            renderJSON(gson.toJson(items));
    

    this can be attached in play.mvc.results.RenderJson class permanent, or as a method param.

  • notalifeform (at gmail)

    notalifeform (at gmail) April 21st, 2014 @ 08:05 PM

    • Milestone changed from 1.3 to 1.4.x
  • adl dl
  • Hard Work

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2>Play framework</h2>

Play makes it easier to build Web applications with Java. It is a clean alternative to bloated Enterprise Java stacks. It focuses on developer productivity and targets RESTful architectures. Learn more on the <a href="http://www.playframework.org">http://www.playframework.org</a> website.<br><br>

<h2>Source code is hosted on github</h2>Check out our repository at <a href="http://github.com/playframework/play">http://github.com/playframework/play</a><br><br>

<h2>Contributing, creating a patch</h2> Please read the <a href="http://play.lighthouseapp.com/projects/57987/contributor-guide">contributor guide</a><br><br>

<h2>Reporting Security Vulnerabilities</h2> Since all bug reports are public, please report any security vulnerability directly to <em>guillaume dot bort at gmail dot com</em>.<br><br>

<h2>Creating a bug report</h2> Bug reports are incredibly helpful, so take time to report bugs and request features in our ticket tracker. We’re always grateful for patches to Play’s code. Indeed, bug reports with attached patches will get fixed far quickly than those without any.<br><br>

Please include as much relevant information as possible including the exact framework version you're using and a code snippet that reproduces the problem.<br><br>

Don't have too much expectations. Unless the bug is really a serious "everything is broken" thing, you're creating a ticket to start a discussion. Having a patch (or a branch on Github we can pull from) is better, but then again we'll only pull high quality branches that make sense to be in the core of Play.

Pages