Я просто хочу вернуть свой пользовательский объект как JSON для использования при вызове ajax на стороне клиента.
Это работало в один момент, и после некоторых обновлений (а именно, изменения приложения для развертывания в / в Jetty) теперь это не так.
Я не выкидываю исключение из кода, он возвращается просто отлично, но, кажется, взрывается где-то в корневом коде в Джексоне при попытке преобразовать объект в JSON.
Как я уже сказал, я не получаю исключения, мой ajax-вызов просто взрывается, сообщая код ошибки «500, Internal Server Error».
/* User contains information about a user of this site, that exists only
* in the context of this site (no names, addresses).
*/
@Entity(name="User")
@Table(name="USER")
@NamedQuery(
name="findUserByName",
query="SELECT OBJECT(u) FROM User u WHERE u.name = :name"
)
public class User extends AuditableEntity implements Serializable {
private static final long serialVersionUID = -1308795024222223320L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id")
private Long id;
@NotEmpty
@MinSkipEmpty(value=6)
@MaxSkipEmpty(value=32)
@Column(name="name", length=32)
private String name;
@NotEmpty
@MinSkipEmpty(value=4)
@MaxSkipEmpty(value=40)
@Column(name="password", length=40)
private String password;
@Column(name="salt", length=40)
private String salt;
@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST})
@JoinColumn(name="person_id")
private Person person;
@Column(name="last_login")
private Date lastLogin;
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name ="USER_AUTHORITY")
@Column(name="authority")
private List<Integer> authorities;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = (name == null ? name : name.trim());
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = (password == null ? password : password.trim());
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Date getLastLogin() {
return lastLogin;
}
public void setLastLogin(Date lastLogin) {
this.lastLogin = lastLogin;
}
public List<Integer> getAuthorities() {
return authorities;
}
public void setAuthorities(List<Integer> authorities) {
this.authorities = authorities;
}
}
Это сущность человека
@Entity(name = "Person")
@Table(name = "PERSON")
public class Person extends AuditableEntity implements Serializable {
private static final long serialVersionUID = -1308795024262635690L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@NotEmpty
@MaxSkipEmpty(value=64)
@Column(name = "firstName", length=64)
private String firstName;
@NotEmpty
@MaxSkipEmpty(value=64)
@Column(name = "lastName", length=64)
private String lastName;
@NotEmpty
@Email
@MaxSkipEmpty(value=256, message="")
@Column(name = "email", length=256)
private String email;
@DateTimeFormat(pattern="MM/dd/yyyy")
@NotNull(message = "Required field")
@Column(name = "date")
private Date birthday;
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "location_id")
private Location location;
public Person() {
}
public Person(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return super.toString() + " name = " + firstName + " " + lastName
+ " id = " + id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
return true;
}
}
@Entity(name = "Location")
@Table(name = "LOCATION")
public class Location extends AuditableEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
//name of person/place/thing
@Column(name = "name", length=128)
String name;
//street address, p.o. box, company name, c/o
@NotEmpty
@MaxSkipEmpty(value=128)
@Column(name = "line_1", length=128)
String line1;
// apt., suite, building, floor, entrance, etc.
@Column(name = "line_2", length=128)
String line2;
@NotEmpty
@MaxSkipEmpty(value=64)
@Column(name = "city", length=64)
String city;
// state, providence, region
@NotEmpty
@MaxSkipEmpty(value=40)
@Column(name = "state", length=40)
String state;
// postal code
@NotEmpty
@MaxSkipEmpty(value=16)
@Column(name = "zip", length=16)
String zip;
@Column(name = "country")
String country;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLine1() {
return line1;
}
public void setLine1(String line1) {
this.line1 = line1;
}
public String getLine2() {
return line2;
}
public void setLine2(String line2) {
this.line2 = line2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
private static final long serialVersionUID = -178898928354655555L;
}
@RequestMapping(value="user/{documentId}", method=RequestMethod.GET)
public @ResponseBody User getUserForDocument( Model model, @PathVariable("documentId") Long docId){
Document doc = null;
try{
doc = dService.find(docId);
}catch(Exception e){
Logger logger = Logger.getLogger(DocumentController.class);
logger.error(e.getMessage());
}
User user = doc.getUser();
user.getPerson();
user.getPerson().getLocation();
return user;
}
@Repository()
public class DocumentDaoImpl implements DocumentDao {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public Document find(Long id) {
Document doc = entityManager.find(Document.class, id);
Hibernate.initialize(doc.getUser());
Hibernate.initialize(doc.getUser().getPerson());
Hibernate.initialize(doc.getUser().getPerson().getLocation());
return doc;
}
@SuppressWarnings("unchecked")
@Transactional
public List<Document> getUnassignedDocumentsForUser(User user) {
Query query = entityManager.createQuery(new StringBuffer()
.append("select d from Document d WHERE d.user = :user ")
.append("AND NOT d IN( SELECT d from Book b, IN(b.docs) bd WHERE bd.id = d.id )")
.append("").toString());
query.setParameter("user", user);
List<Document> tmp = (ArrayList<Document>) query.getResultList();
for(Document doc : tmp){
Hibernate.initialize(doc);
Hibernate.initialize(doc.getUser());
Hibernate.initialize(doc.getUser().getPerson());
Hibernate.initialize(doc.getUser().getPerson().getLocation());
entityManager.detach(doc);
entityManager.detach(doc.getUser());
entityManager.detach(doc.getUser().getPerson());
entityManager.detach(doc.getUser().getPerson().getLocation());
}
return tmp;
}
@Transactional
public Document save(Document doc) {
if (doc.getId() == null) {
entityManager.persist(doc);
return doc;
} else {
return entityManager.merge(doc);
}
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
ErrorExceptionResolver:
@Component
public class BWHandlerExceptionResolver extends SimpleMappingExceptionResolver implements InitializingBean{
public void afterPropertiesSet() throws Exception {
Properties props = new Properties();
props.put(Exception.class.getName(),"error");
this.setExceptionMappings(props);
}