2

Page entity.

@Entity
@Table(name = "pages", schema = "admin")
public class Page implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true)
    private Integer id;

    @Column(name = "name")
    private String name;


    @ManyToOne(targetEntity = Partition.class, fetch = FetchType.LAZY)
    private Partition partition;

    @Column(name = "is_startable")
    private Boolean isStartable;

    @Column(name = "priority")
    private Integer priority;

    @Column(name = "prefix_granted_authority")
    private String prefixGrantedAuthority;

    @OneToMany(mappedBy = "page", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private List<Permission> permissions;

    @Column(name = "link", unique = true)
    private String link;

PageRepository

    List<Page> findByPermissionsGroupsOrderByPartitionNameAscNameAsc(@Param(value = "group") Group group);

PageServiceImpl

    @Override
public Collection<Page> getAccessedPages(Group group) {
    try {
          List<Page> pages = pageRepository.findByPermissionsGroupsOrderByPartitionNameAscNameAsc(group);
        return pages;
    } catch (Exception ex) {
        logger.error("getPage error", ex);
        return null;
    }
}

getAccessedPages return real List of page entities(not null), but all fields in entities are null.

Why?

fmodos
  • 4,472
  • 1
  • 16
  • 17
wolandec
  • 161
  • 4
  • 15
  • are you accessing those entities inside or outside transaction? – user902383 Dec 15 '14 at 13:37
  • Repository method will return an empty list (not null, but no entities) if no results are found. Are you sure you are getting real entities? What is the result list size? – Predrag Maric Dec 15 '14 at 13:39
  • No transactions used and size of list is not 0, it reflects the real query result size. – wolandec Dec 15 '14 at 13:58
  • How are you checking that fields are null? In debugger? If you print for example `page.getId()` is it still null? Debuggers mostly use reflection to display field values, which are sometimes initialized only after you call their getter method. – Predrag Maric Dec 15 '14 at 15:04
  • Yes, debugger in Eclipse Luna. Actually in the controller I have the same result. Pages returned from service still filled by null values. And after all, Jackson serialize that list in something like this [{},{},{},{}]. – wolandec Dec 15 '14 at 19:15
  • @user902383 What do you mean when asked me about transaction? I noticed that other methods in PageServiceImpl has '@Transactional' annotation. And when I invoke the getId() method, it returns me the valid value. – wolandec Dec 16 '14 at 12:45

2 Answers2

1

I also encounter this problem while ago, it looks like spring data does some kind lazy instantiation.
So if you not access this fields inside of your transaction, they will stay null. Add annotation @Transactional on method where are you calling this request and problem will be solved.

jFrenetic
  • 5,384
  • 5
  • 42
  • 67
user902383
  • 8,420
  • 8
  • 43
  • 63
  • @wolandec i can't find any reference for you to have a look, but for me it looks like when you get your data, spring data does not returns you your entity but its proxy. Proxy is not populated till you actually request some data from them. When transaction is finished, entity is no longer managed. – user902383 Dec 17 '14 at 10:00
  • Ok, what about other methods in that service, without @Transactional annotation working perfectly in the same conditions? – wolandec Dec 19 '14 at 18:39
0

I wanted to expand on @user902383's answer, which ultimately also solved my issue, but it was too long for a comment.

In my case, I had repository method fetching an entity, Helper, called inside a @PostLoad listener that used Helper for calculations for filling a field in another entity, Child. The listener method was already annotated with org.springframework.transaction.annotation.Transactional.

When called by Child's repository it fetched a Helper entity with all fields filled, but when called by the repository of an entity Parent which had a child Child, it fetched an empty Helper object with only the id filled even though it was properly annotated.

The issue was that I was using this hack to access the repository outside of a Spring @Component (I couldn't make the listener a component). I suspect that the Spring magic for detecting when a field is dereferenced in a @Transactional method does not work when the repository was not properly @Autowired. I still do not know why it worked in Child's repository but not in Parent.

My solution to this particular problem was moving the repository call and dereferencing to a @Service, which properly @Autowires the repository, and doing the hackish static call for getting that service instead, which makes for better code structure anyway.

Sofia Paixão
  • 309
  • 2
  • 16