I have a table with two fields I would like to have two objects.
First one only has field1
@Entity(name = \"simpleTableObject\")
@Table(name = \"someTabl
I was able to do something about your question. I defined another class hierarchy: UserWithRole that extends User which is similar to yours.
User
as an entity with inheritance strategy SINGLE_TABLE
:@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@Column(nullable = false)
protected String name;
// toString(), default constructor, setters/getters, more constructors.
...
}
This inheritance strategy has one considerable disadvantage:
There is another strategy JOINED
that allows creating non-nullable columns in subclasses. It creates an additional table for each subclass these tables have FK to the superclass table.
UserWithRole
class:@Entity
public class UserWithRole extends User {
private String role;
// toString(), default constructor, setters/getters, more constructors.
...
}
Helper
class to create users in the database and use your query:@Component
public class Helper {
@Autowired
EntityManager entityManager;
@Transactional
public void createUsers() {
for (long i = 0; i < 10; i++) {
User user;
if (i % 2 == 0) {
user = new UserWithRole("User-" + i, "Role-" + i);
} else {
user = new User("User-" + i);
}
entityManager.persist(user);
}
entityManager.flush();
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public < T > List < T > get(Class < T > aClass) {
SessionFactory sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactory.class);
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(aClass);
if (hibernateMetadata == null) {
return null;
}
if (hibernateMetadata instanceof AbstractEntityPersister) {
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String entityName = persister.getEntityName();
if (entityName != null) {
return sessionFactory.getCurrentSession().
createQuery("from " + entityName).list();
}
}
return null;
}
}
As you may see, I changed your method a bit:
User
instances:@Test
public void testQueryUsers() {
helper.createUsers();
for (User user: helper.get(User.class)) {
System.out.println(user);
}
}
Output (users with role are still UserWithProfile
instances at runtime):
UserWithRole{id=1, name='User-0', role='Role-0'}
User{id=2, name='User-1'}
UserWithRole{id=3, name='User-2', role='Role-2'}
User{id=4, name='User-3'}
UserWithRole{id=5, name='User-4', role='Role-4'}
User{id=6, name='User-5'}
UserWithRole{id=7, name='User-6', role='Role-6'}
User{id=8, name='User-7'}
UserWithRole{id=9, name='User-8', role='Role-8'}
User{id=10, name='User-9'}
SQL query issued by Hibernate:
select
user0_.id as id2_0_,
user0_.name as name3_0_,
user0_.role as role4_0_,
user0_.dtype as dtype1_0_
from
users user0_
UserWithProfile
instances:@Test
public void testQueryUsersWithProfile() {
helper.createUsers();
for (User user: helper.get(UserWithRole.class)) {
System.out.println(user);
}
}
Output:
UserWithRole{id=1, name='User-0', role='Role-0'}
UserWithRole{id=3, name='User-2', role='Role-2'}
UserWithRole{id=5, name='User-4', role='Role-4'}
UserWithRole{id=7, name='User-6', role='Role-6'}
UserWithRole{id=9, name='User-8', role='Role-8'}
SQL query issued by Hibernate:
select
userwithro0_.id as id2_0_,
userwithro0_.name as name3_0_,
userwithro0_.role as role4_0_
from
users userwithro0_
where
userwithro0_.dtype = 'UserWithRole'
Please, let me know if it's what you were looking for.