I am a bit confused in regards to abstract classes and help would be great.
I have a the following classes
public abstract class AbstractUser{
private String username;
private String password;
}
And then I have this class
#Entity
public class Company extends AbstractUser{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String company_name
}
Now when I launch the application and I check the h2-console, the table Company only has the id and company_name. not the abstract classes variables. Is there a way to make it so it gets all the variables?
thank you in advance
You can use #MappedSuperclass Jpa annotation on the AbstractUser, Also consider moving the id attribute to the abstract class.
#MappedSuperclass
public abstract class AbstractUser{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
}
To resolve this, you will need JPA annotation on your abstract class. This is not specific to Spring Boot, it's JPA thing.
You can apply #MappedSuperclass on your abstract class and that should resolve this issue. Find More: Inherit Super Class Properties
Related
I have this generic entity:
#MappedSuperclass
abstract class Position<T> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Enumerated(EnumType.STRING)
private T name;
}
But there's a case where the generic type is a String:
#Entity
class ChildPosition0 extends Position<String> {
}
And, JPA will complaint that String is not an enum in this case, but I need to annotate this name field if it's an enum, if not, the database will mark it as int type, and that's not ideal. How do I solve this? How to annotate the field conditionally?
My workaround:
Use Position as a parent class, and adding those field in child class individually, even though they share the same field:
#MappedSuperclass
abstract class Position {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
And extends it from child entity like this:
Child1:
#Entity
public class ChildPosition1 extends Position {
#Enumerated(EnumType.STRING)
private Priority name; // <- Priority is enum type
}
Child2:
#Entity
public class ChildPosition2 extends Position {
private String name;
}
This is too ugly IMO. And Java does not allow class field override from child class. So, back to the question: how to annotate generic field conditionally?
When saving the Dater class below with Neo4jRepository::save (spring-data-neo4j-6.1.5) the save hangs and never returns. I believe it has something to do with my Dater object having a relationship defined by a set referencing an interface instead of a class with a #Node annotation. Is this an issue for neo4j?
//PersistentDaterMusicItem is interface. Is there a problem doing this?
#Relationship(type = "LISTENS_TO_MUSIC")
private Set<PersistentDaterMusicItem> musicItems = new HashSet<>();
//parent
#Node
public class Dater{
#Id
#GeneratedValue
//set of different implementations of PersistentDaterMusicItem
#Relationship(type = "LISTENS_TO_MUSIC")
private Set<PersistentDaterMusicItem> musicItems = new HashSet<>();
}
//inteface 1
public interface PersistentLibraryMusicItem extends PersistentDaterMusicItem{
LocalDateTime getAddedDateTime();
}
//interface 2
public interface PersistentListenedMusicItem extends PersistentDaterMusicItem{
LocalDateTime getListenedDateTime();
}
//impl 1 of PersistentDaterMusicItem
#Node
public class ListenedAppleSong extends AppleSong implements PersistentListenedMusicItem{
#Id
#GeneratedValue
private final Long id;
}
//impl 2 of PersistentDaterMusicItem
#Node
public class LibraryAppleSong extends AppleSong implements PersistentLibraryMusicItem{
#Id
#GeneratedValue
private final Long id;
}
It turns out the problem was unrelated to what I thought. My constructor to ListenedAppleSong took an argument that was not a field of the class. Since Spring data expects constructor args to exist as fields it was failing with error: "Required property appleSong not found for class com.dapp.common.model.apple.ListenedAppleSong!" Solution was to make sure all constructor args are fields in the class. Unfortunately this error was not thrown during execution and the code just hung so it took a while to debug.
I saw similar questions, but answers weren't helpful. So, i get this error:
Use of #OneToMany or #ManyToMany targeting an unmapped class: com.podro.model.Journey.roadWay[com.podro.model.RoadElement]
I'm trying to create List with objects of RoadElements (which is interface for class Point and Section). There is any other way to do it? From what i know, i guess that is the only way to create proper mapping for this classes, and have list of this elements.
#Entity
#Table(name="Journey")
public class Journey {
// Some other fields
#Column(name="road_way")
#ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private List<RoadElement> roadWay;
}
#MappedSuperclass
public interface RoadElement {}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#Table(name="Point")
public class Point implements RoadElement{
#Id
#Column(name="id")
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
private String name;
#Column(name="time_in_days")
private int timeInDays;
private Rate rating;
}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#Table(name="Section")
public class Section implements RoadElement{
#Id
#Column(name="id")
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
#Column(name="section_name" , length=100)
private String sectionName;
#Column(name="time_in_days")
private int timeInDays;
#Column(name="kind_of_transport")
private Locomotion kindOfTransport;
}
Thanks for answers, I would be very grateful for help!
Associations are between entities. RoadElement is not an entity. It's an interface.
You may not do what you're trying to do. Hibernate needs to know the type of the entities contained in roadWay.
So, RoadElement should be a class, annotated with #Entity, having an ID that uniquely identifies a RoadElement among all the road elements (sections, points, etc.)
Section and Point should extend from RoadElement, and should NOT have their own ID, since it's inherited from RoadElement.
class A implements Serializable{
private static final long serialVersionUID = 1L;
#Id
Integer id;
...
// constructor getter and setter
}
#Entity
class B extends A{
private static final long serialVersionUID = 1L;
#Column
String name;
#Column
String age;
...
//constructors, getters and setters
}
As you see above, class A extends from class B, B should have the identifier id inheritance from A. but i got the No identifier specified for entity: com.d.e.B
what did i missed? thanks in advance.
You missed the #MappedSuperclass annotation on A, to tell Hibernate/JPA that properties and JPA annotations found in A must be considered.
In this example, #MapperSuperclass will work.
If you have entity relationships (one to many, many to one, etc...) the A class should be defined as an entity and the #Inheritance annotation should be used instead.
I had the same error ("No identifier specified for entity") because my A class had the #Inheritance annotation but not the #Entity annotation
I'm trying to duplicate something you can do in .Net but not having much luck.
Is the following not possible in Java or am I just missing something? When I run it I get told there is no identifier specified for entity Group.
public abstract class RCEntity
{
#Id #GeneratedValue
private int id;
//getters & setters
}
#Entity
public class Group extends RCEntity {
}
Add the annotation #MappedSuperclass to your super class, i.e.
#MappedSuperclass
public abstract class RCEntity
{
#Id #GeneratedValue
private int id;
//getters & setters
}
From this section in the docs:
Any class in the hierarchy non annotated with #MappedSuperclass nor #Entity will be ignored.