We have the following situation: an entity and a pojo in Objectify v5.
As you can see, the entityclass has a reference to the pojo, like this:
#Entity
public class TestCustomer {
#Id
public Long id;
TestIbj ibj;
}
class TestIbj {
TestCustomer customer;
}
This fails with a StackOverflowError when we try to save it like this:
TestCustomer testCustomer = new TestCustomer();
OfyService.ofy().save().entity(testCustomer).now();
Error:
java.lang.StackOverflowError
at java.lang.Class.getMethod0(Class.java:2772)
at java.lang.Class.isCheckMemberAccessOverridden(Class.java:2214)
at java.lang.Class.checkMemberAccess(Class.java:2233)
at java.lang.Class.getDeclaredMethods(Class.java:1854)
at...
Our question is: Why is this not allowed/failing? If we change the pojo into an Entity, it works fine, but we don't understand why that is..
Thank you very much!
StackoverflowError almost always means that there is an unbounded recursion. It's the case in your code as well:
#Entity
public class TestCustomer {
#Id
public Long id;
TestIbj ibj; // TestCustomer contains TestIbj
}
class TestIbj {
TestCustomer customer; // TestIbj contains TestCustomer (which further contains TestIbj.. and so on)
}
Due to this circular dependency (shown in code above), objectify will never be able to construct object graph.
Related
I'm new to Spring, I fear this question may be duplicate, as there are numerous ways to do get resource from database to drop-down which I don't understand, so I'm asking if anyone can help me by fixing my code or with their own code which matches with mine as it'll be easy for me to learn.
My POJO
#Entity
#Table(name = "emp69")
public class Emp {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String designation;
....Constructor with name & designation field...
......getters method and setters method.....
My Repository
public interface EmpRepository extends JpaRepository<Employee, Integer> {
#Modifying
#Query(
value = "select designation from employee",
nativeQuery = true
)
List<String> designation();
}
My Data Access Object
#Service
public class EmployeeDao {
#Autowired
private EmpRepository repo;
#Transactional
public List<String> desig() {
return repo.designation();
}
}
My Controller
#Controller
public class EmployeeController {
#Autowired
EmployeeDao dao;
#RequestMapping("/empform")
public String showform(Model m) {
List<String> designation= dao.designation();
m.addAttribute("designation", designation);
return "empform";
}
}
My JSP page
<select>
<c:forEach var="dd" items="${designation}">
<option><c:set var="dd.designation">${dd.designation }</c:set></option>
</c:forEach>
</select>
seems everything fine to me but when I execute, it gives
Property [designation] not found on type [java.lang.String]
error.
And on STS console
javax.el.PropertyNotFoundException: Property [designation] not found on type [java.lang.String]
Your Controller, Service & Repository part are correct but it seems like you haven't studied JSP well. I'll suggest you to take a step back from a big framework and individually learn each of its aspects first like JSP, JSTL, etc. Following this path will lead you to understanding of big frameworks and everything will be more clear.
Anyhow here's your answer..
<select>
<c:forEach var="dd" items="${designation}">
<option><c:set var="d" value="${dd}" /><c:out value="${d }"/></option>
</c:forEach>
</select>
just replace this part in your code..
Hope it helps
I already know how to add annotation based validation on specific attributes in Entity class like :-
public class Person {
#NotNull
private String firstName;
private String lastName;
//...
}
But is it possible to add annotation on class Person, in order to validate all the attributes inside this class, by creating a Customised Validation Class and handling validation there somewhere like :-
#Retention(value = RetentionPolicy.RUNTIME)
#Target(value = ElementType.METHOD)
public #interface PersonneName {
public String firstName();
}
I am working on a project to get Constraints from Database and creating Customised Validation Class and applying on the Entity class attributes according to the constaints got from DB.
Please suggest.
Yes, of course, it's possible. First, create the definition of your annotation. Pretty much like you did in your example, however, with a different #Target type
#Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = PersonValidator.class)
public #interface ValidPerson {
String message () default "Your custom message";
Class<?>[] groups () default {};
Class<? extends Payload>[] payload () default {};
}
Then implement the validator whose isValid method takes the instance of your Person class:
public class PersonValidator implements ConstraintValidator<ValidPerson, Person> {
#Override
public boolean isValid (Person person, ConstraintValidatorContext context) {
// your validation logic
}
}
Sure it is possible, just check the documentation regarding how to write custom class level constraints - http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-class-level-constraints
The important thing of course is that you make sure that one can actually place the constraint annotation on the type level. For that you need to add ElementType.TYPE to the #Target annotation.
I have two tables CatalogueBase and CatalogueCopydetails now i am using Hibernate search for CatalogueBase table but i wanted to search even in CatalogueCopydetails table. This two tables are related with #ManyToOne (i.e CatalogueCopydetails using CatalogueBase id as foreign key), hear for one entry of CatalogueBase their will be 'n' numbers of CatalogueCopydetails
CatalogueBase POJO Class
#Indexed
#JsonAutoDetect
#Entity
#Table(name="catalogueBase")
public class CatalogueBase extends BaseObject implements Serializable {
private Long id;
......
#Id
#GeneratedValue
#Column(name="id")
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
....
CatalogueCopydetails POJO Class
#JsonAutoDetect
#Entity
#Table(name="cataloguecopydetails")
public class CatalogueCopyDetails extends BaseObject implements Serializable {
private CatalogueBase catalogueBase;
......
#ManyToOne
#JoinColumn(name="cataloguebaseid" , insertable=true, updatable=true,nullable=true)
public CatalogueBase getCatalogueBase() {
return catalogueBase;
}
public void setCatalogueBase(CatalogueBase catalogueBase) {
this.catalogueBase = catalogueBase;
}
......
at least how can i use #IndexedEmbedded for this scenario (i don't think i can use #IndexedEmbedded because CatalogueBase have no relation to CatalogueCopyDetails like OneToOne or OneToMany etc only CatalogueCopyDetails references CatalogueBase )
how can i do this..?, any help will be appreciated, Thanks.
The easiest way would of course be to make the relation bidirectional. Is there a good reason why you don't want to do that? The other thing you could do is to add #Indexed to CatalogueCopyDetails as well and use #IndexedEmbedded on CatalogueBase. You could then write a query using the CatalogueCopyDetails index. Whether this works will depend on your use case and what you actually want as result of query.
I am trying to learn MVC 3/4 using visual studio 2012. I have created a view, a model and controller. VS created all the database stuff for me. It added a gridview for me where I can add a new row, edit or delete too. I would like to change the way it selects the rows from the database. I know that I have to change the DbContext for that.
here is my DbContext,
public class ApartmentContext : DbContext
{
public ApartmentContext() : base("name=ApartmentContext")
{
}
// this part has to be changed****
public DbSet<Apartment> Apartments { get; set; }
}
public DbSet Apartments{...} returns the list I guess, but I want to change the way it selects the rows. For example; I want to select the rows whose "flag" column is set to 1. how do I do that?
thanks
You should filter your results in the related controller, not in the DbContext. It could be like this in that controller:
...
ApartmentContext db = new ApartmentContext();
var apartments = db.Apartments.Where(a => a.Flag == 1);
...
and then use apartment object to render your view
You need to create query. Object Apartments represents table in database, not a list.
You can also use entity framework dbconext to execute your TSQL Statement or stored procedure. Following is a link for that.
http://www.dotnetjalps.com/2012/04/execute-tsql-statement-with.html
An alternative is to have a wrapping interface around the context to hide these details, so that is applies to every query transparently:
// Wrapping interface
public interface IApartmentRepository
{
IQueryable<Apartment> Apartments { get; }
}
// As before
public class ApartmentContext : DbContext
{
...
}
// Implementing class, hiding the DbContext object
public class EFApartmentRepository : IApartmentRepository
{
private ApartmentContext context = new ApartmentContext();
public IQueryable<Apartment> Apartments
{
get { return this.context.Apartments.Where(a => a.Flag == 1); }
}
}
// Your controller uses DI to get the controller
public class HomeController : Controller
{
private IApartmentRepository apartmentContext;
public HomeController( IApartmentRepository rep )
{
this.apartmentContext = rep;
}
}
The controllers IApartmentRepository parameter can be hooked up to the EFApartmentRepository by overidding the DefaultControllerFactory class. You use a DI framework like NInject or StructureMap to insert the correct implementation into the constructor at runtime.
Assuming I have an Interface IReportBuilderService and concrete class ReportBuilderService
e.g. public class ReportBuilderService : IReportBuilderService { }
I can start to mock this service with Moq as such
Mock<IReportBuilderService> _reportBuilderServiceMock = new Mock<IReportBuilderService>();
And mock expectations etc on the mock class, ok no problems.
Question: How do I mock the following method signature?
public abstract class ReportBuilder<TReport> where TReport : Report, new()
where a TReport is defined as
public class SomeReport : ReportBuilder<Report>, IMapper{}
And Report class is simply
public class Report { }
In the abstract class ReportBuilder there are a series of Property Get/ Sets, it is the value of these that I’m trying to fake/mock.
But I can’t begin to get the correct mock on this abstract class to start with
Hope this makes sense
Given that your abstract class looks like this:
public abstract class ReportBuilder<TReport> where TReport : Report, new()
{
public abstract Int32 SomeThing { get; set; }
}
there's no problem in mocking it at all:
var m = new Mock<ReportBuilder<Report>>();
m.SetupProperty(r => r.SomeThing, 19);
but note that all your properties have to be virtual or abstract.
So if this is not the case (and you can't or don't want to change this), you could either extract an interface from your base class and use this (if you're willing to change your code accordingly), or simply create a stub/mock by subclassing:
public class StubReportBuilder : ReportBuilder<Report>
{
public override Int32 SomeThing { get { return 42; } set { } }
}